2 Copyright (c) 2011, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
10 * The ProfilerViewer module provides a graphical display for viewing
11 * the output of the YUI Profiler <http://developer.yahoo.com/yui/profiler>.
12 * @module profilerviewer
13 * @requires yahoo, dom, event, element, profiler, yuiloader
17 * A widget to view YUI Profiler output.
18 * @namespace YAHOO.widget
19 * @class ProfilerViewer
20 * @extends YAHOO.util.Element
22 * @param {HTMLElement | String | Object} el(optional) The html
23 * element into which the ProfileViewer should be rendered.
24 * An element will be created if none provided.
25 * @param {Object} attr (optional) A key map of the ProfilerViewer's
26 * initial attributes. Ignored if first arg is an attributes object.
28 YAHOO.widget.ProfilerViewer = function(el, attr) {
30 if (arguments.length == 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
32 el = attr.element || null;
34 if (!el && !attr.element) {
35 el = this._createProfilerViewerElement();
38 YAHOO.widget.ProfilerViewer.superclass.constructor.call(this, el, attr);
44 YAHOO.extend(YAHOO.widget.ProfilerViewer, YAHOO.util.Element);
46 // Static members of YAHOO.widget.ProfilerViewer:
47 YAHOO.lang.augmentObject(YAHOO.widget.ProfilerViewer, {
49 * Classname for ProfilerViewer containing element.
59 * Classname for ProfilerViewer button dashboard.
61 * @property CLASS_DASHBOARD
64 * @default "yui-pv-dashboard"
66 CLASS_DASHBOARD: 'yui-pv-dashboard',
69 * Classname for the "refresh data" button.
71 * @property CLASS_REFRESH
74 * @default "yui-pv-refresh"
76 CLASS_REFRESH: 'yui-pv-refresh',
79 * Classname for busy indicator in the dashboard.
81 * @property CLASS_BUSY
84 * @default "yui-pv-busy"
86 CLASS_BUSY: 'yui-pv-busy',
89 * Classname for element containing the chart and chart
92 * @property CLASS_CHART_CONTAINER
95 * @default "yui-pv-chartcontainer"
97 CLASS_CHART_CONTAINER: 'yui-pv-chartcontainer',
100 * Classname for element containing the chart.
102 * @property CLASS_CHART
105 * @default "yui-pv-chart"
107 CLASS_CHART: 'yui-pv-chart',
110 * Classname for element containing the chart's legend.
112 * @property CLASS_CHART_LEGEND
115 * @default "yui-pv-chartlegend"
117 CLASS_CHART_LEGEND: 'yui-pv-chartlegend',
120 * Classname for element containing the datatable.
122 * @property CLASS_TABLE
125 * @default "yui-pv-table"
127 CLASS_TABLE: 'yui-pv-table',
130 * HTML strings used in the UI. Values will be inserted into DOM with innerHTML.
135 * @default English language strings for UI.
138 title: "YUI ProfilerViewer",
140 viewprofiler: "View Profiler Data",
141 hideprofiler: "Hide Profiler Report",
142 showchart: "Show Chart",
143 hidechart: "Hide Chart",
144 refreshdata: "Refresh Data"
147 //key: [column head label, width in pixels]
148 fn: ["Function/Method", null], //must auto-size
149 calls: ["Calls", 40],
150 avg: ["Average", 80],
151 min: ["Shortest", 70],
152 max: ["Longest", 70],
153 total: ["Total Time", 70],
156 millisecondsAbbrev: "ms",
157 initMessage: "initialiazing chart...",
158 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>."
162 * Function used to format numbers in milliseconds
163 * for chart; must be publicly accessible, per Charts spec.
165 * @property timeAxisLabelFunction
169 timeAxisLabelFunction: function(n) {
170 var a = (n === Math.floor(n)) ? n : (Math.round(n*1000))/1000;
171 return (a + " " + YAHOO.widget.ProfilerViewer.STRINGS.millisecondsAbbrev);
175 * Function used to format percent numbers for chart; must
176 * be publicly accessible, per Charts spec.
178 * @property percentAxisLabelFunction
182 percentAxisLabelFunction: function(n) {
183 var a = (n === Math.floor(n)) ? n : (Math.round(n*100))/100;
192 // STANDARD SHORTCUTS
194 var Dom = YAHOO.util.Dom;
195 var Event = YAHOO.util.Event;
196 var Profiler = YAHOO.tool.Profiler;
197 var PV = YAHOO.widget.ProfilerViewer;
198 var proto = PV.prototype;
206 * Refreshes the data displayed in the ProfilerViewer. When called,
207 * this will invoke a refresh of the DataTable and (if displayed)
209 * @method refreshData
213 proto.refreshData = function() {
214 this.fireEvent("dataRefreshEvent");
218 * Returns the element containing the console's header.
220 * @return HTMLElement
223 proto.getHeadEl = function() {
224 return (this._headEl) ? Dom.get(this._headEl) : false;
228 * Returns the element containing the console's body, including
229 * the chart and the datatable..
231 * @return HTMLElement
234 proto.getBodyEl = function() {
235 return (this._bodyEl) ? Dom.get(this._bodyEl) : false;
239 * Returns the element containing the console's chart.
241 * @return HTMLElement
244 proto.getChartEl = function() {
245 return (this._chartEl) ? Dom.get(this._chartEl) : false;
249 * Returns the element containing the console's dataTable.
251 * @return HTMLElement
254 proto.getTableEl = function() {
255 return (this._tableEl) ? Dom.get(this._tableEl) : false;
259 * Returns the element containing the console's DataTable
261 * @method getDataTable
262 * @return YAHOO.widget.DataTable
265 proto.getDataTable = function() {
266 return this._dataTable;
270 * Returns the element containing the console's Chart instance.
272 * @return YAHOO.widget.BarChart
275 proto.getChart = function() {
281 // PRIVATE PROPERTIES
283 proto._rendered = false;
284 proto._headEl = null;
285 proto._bodyEl = null;
286 proto._toggleVisibleEl = null;
287 proto._busyEl = null;
290 proto._tableEl = null;
291 proto._dataTable = null;
293 proto._chartEl = null;
294 proto._chartLegendEl = null;
295 proto._chartElHeight = 250;
297 proto._chartInitialized = false;
303 proto._init = function() {
309 * Fired when a data refresh is requested. No arguments are passed
312 * @event refreshDataEvent
314 this.createEvent("dataRefreshEvent");
317 * Fired when the viewer canvas first renders. No arguments are passed
322 this.createEvent("renderEvent");
324 this.on("dataRefreshEvent", this._refreshDataTable, this, true);
326 this._initLauncherDOM();
328 if(this.get("showChart")) {
329 this.on("sortedByChange", this._refreshChart);
335 * If no element is passed in, create it as the first element
337 * @method _createProfilerViewerElement
338 * @return HTMLElement
341 proto._createProfilerViewerElement = function() {
343 var el = document.createElement("div");
344 document.body.insertBefore(el, document.body.firstChild);
345 Dom.addClass(el, this.SKIN_CLASS);
346 Dom.addClass(el, PV.CLASS);
351 * Provides a readable name for the ProfilerViewer instance.
356 proto.toString = function() {
357 return "ProfilerViewer " + (this.get('id') || this.get('tagName'));
361 * Toggles visibility of the viewer canvas.
362 * @method _toggleVisible
366 proto._toggleVisible = function() {
368 var newVis = (this.get("visible")) ? false : true;
369 this.set("visible", newVis);
373 * Shows the viewer canvas.
378 proto._show = function() {
380 this._setBusyState(true);
381 if(!this._rendered) {
382 var loader = new YAHOO.util.YUILoader();
383 if (this.get("base")) {
384 loader.base = this.get("base");
387 var modules = ["datatable"];
388 if(this.get("showChart")) {
389 modules.push("charts");
392 loader.insert({ require: modules,
393 onSuccess: function() {
398 var el = this.get("element");
399 Dom.removeClass(el, "yui-pv-minimized");
400 this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.hideprofiler;
402 //The Flash Charts component can't be set to display:none,
403 //and even after positioning it offscreen the screen
404 //may fail to repaint in some browsers. Adding an empty
405 //style rule to the console body can help force a repaint:
406 Dom.addClass(el, "yui-pv-null");
407 Dom.removeClass(el, "yui-pv-null");
409 //Always refresh data when changing to visible:
416 * Hides the viewer canvas.
421 proto._hide = function() {
422 this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.viewprofiler;
423 Dom.addClass(this.get("element"), "yui-pv-minimized");
427 * Render the viewer canvas
432 proto._render = function() {
434 Dom.removeClass(this.get("element"), "yui-pv-minimized");
436 this._initViewerDOM();
437 this._initDataTable();
438 if(this.get("showChart")) {
439 this._initChartDOM();
442 this._rendered = true;
443 this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.hideprofiler;
445 this.fireEvent("renderEvent");
450 * Set up the DOM structure for the ProfilerViewer launcher.
451 * @method _initLauncherDOM
454 proto._initLauncherDOM = function() {
456 var el = this.get("element");
457 Dom.addClass(el, PV.CLASS);
458 Dom.addClass(el, "yui-pv-minimized");
460 this._headEl = document.createElement("div");
461 Dom.addClass(this._headEl, "hd");
463 var s = PV.STRINGS.buttons;
464 var b = (this.get("visible")) ? s.hideprofiler : s.viewprofiler;
466 this._toggleVisibleEl = this._createButton(b, this._headEl);
468 this._refreshEl = this._createButton(s.refreshdata, this._headEl);
469 Dom.addClass(this._refreshEl, PV.CLASS_REFRESH);
471 this._busyEl = document.createElement("span");
472 this._headEl.appendChild(this._busyEl);
474 var title = document.createElement("h4");
475 title.innerHTML = PV.STRINGS.title;
476 this._headEl.appendChild(title);
478 el.appendChild(this._headEl);
480 Event.on(this._toggleVisibleEl, "click", this._toggleVisible, this, true);
481 Event.on(this._refreshEl, "click", function() {
483 this._setBusyState(true);
484 this.fireEvent("dataRefreshEvent");
490 * Set up the DOM structure for the ProfilerViewer canvas,
491 * including the holder for the DataTable.
492 * @method _initViewerDOM
495 proto._initViewerDOM = function() {
497 var el = this.get("element");
498 this._bodyEl = document.createElement("div");
499 Dom.addClass(this._bodyEl, "bd");
500 this._tableEl = document.createElement("div");
501 Dom.addClass(this._tableEl, PV.CLASS_TABLE);
502 this._bodyEl.appendChild(this._tableEl);
503 el.appendChild(this._bodyEl);
507 * Set up the DOM structure for the ProfilerViewer canvas.
508 * @method _initChartDOM
511 proto._initChartDOM = function() {
513 this._chartContainer = document.createElement("div");
514 Dom.addClass(this._chartContainer, PV.CLASS_CHART_CONTAINER);
516 var chl = document.createElement("div");
517 Dom.addClass(chl, PV.CLASS_CHART_LEGEND);
519 var chw = document.createElement("div");
521 this._chartLegendEl = document.createElement("dl");
522 this._chartLegendEl.innerHTML = "<dd>" + PV.STRINGS.initMessage + "</dd>";
524 this._chartEl = document.createElement("div");
525 Dom.addClass(this._chartEl, PV.CLASS_CHART);
527 var msg = document.createElement("p");
528 msg.innerHTML = PV.STRINGS.installFlashMessage;
529 this._chartEl.appendChild(msg);
531 this._chartContainer.appendChild(chl);
532 chl.appendChild(chw);
533 chw.appendChild(this._chartLegendEl);
534 this._chartContainer.appendChild(this._chartEl);
535 this._bodyEl.insertBefore(this._chartContainer,this._tableEl);
540 * Create anchor elements for use as buttons. Args: label
541 * is text to appear on the face of the button, parentEl
542 * is the el to which the anchor will be attached, position
543 * is true for inserting as the first node and false for
544 * inserting as the last node of the parentEl.
545 * @method _createButton
548 proto._createButton = function(label, parentEl, position) {
549 var b = document.createElement("a");
550 b.innerHTML = b.title = label;
553 parentEl.appendChild(b);
555 parentEl.insertBefore(b, parentEl.firstChild);
562 * Set's console busy state.
563 * @method _setBusyState
566 proto._setBusyState = function(b) {
568 Dom.addClass(this._busyEl, PV.CLASS_BUSY);
571 Dom.removeClass(this._busyEl, PV.CLASS_BUSY);
577 * Generages a sorting function based on current sortedBy
579 * @method _createProfilerViewerElement
582 proto._genSortFunction = function(key, dir) {
585 return function(a, b) {
586 if (direction == YAHOO.widget.DataTable.CLASS_ASC) {
587 return a[by] - b[by];
589 return ((a[by] - b[by]) * -1);
595 * Utility function for array sums.
599 var _arraySum = function(arr){
601 for(var i = 0; i < arr.length; ct+=arr[i++]){}
606 * Retrieves data from Profiler, filtering and sorting as needed
607 * based on current widget state. Adds calculated percentage
608 * column and function name to data returned by Profiler.
609 * @method _getProfilerData
612 proto._getProfilerData = function() {
614 var obj = Profiler.getFullReport();
618 if (YAHOO.lang.hasOwnProperty(obj, name)) {
621 o.fn = name; //add function name to record
622 o.points = r.points.slice(); //copy live array
627 o.total = _arraySum(o.points);
629 var f = this.get("filter");
632 totalTime += o.total;
637 //add calculated percentage column
638 for (var i = 0, j = arr.length; i < j; i++) {
639 arr[i].pct = (totalTime) ? (arr[i].total * 100) / totalTime : 0;
642 var sortedBy = this.get("sortedBy");
643 var key = sortedBy.key;
644 var dir = sortedBy.dir;
646 arr.sort(this._genSortFunction(key, dir));
653 * Set up the DataTable.
654 * @method _initDataTable
657 proto._initDataTable = function() {
661 //Set up the JS Function DataSource, pulling data from
663 this._dataSource = new YAHOO.util.DataSource(
665 return self._getProfilerData.call(self);
668 responseType: YAHOO.util.DataSource.TYPE_JSARRAY,
672 var ds = this._dataSource;
676 fields: [ "fn", "avg", "calls", "max", "min", "total", "pct", "points"]
679 //Set up the DataTable.
680 var formatTimeValue = function(elCell, oRecord, oColumn, oData) {
681 var a = (oData === Math.floor(oData)) ? oData : (Math.round(oData*1000))/1000;
682 elCell.innerHTML = a + " " + PV.STRINGS.millisecondsAbbrev;
685 var formatPercent = function(elCell, oRecord, oColumn, oData) {
686 var a = (oData === Math.floor(oData)) ? oData : (Math.round(oData*100))/100;
687 elCell.innerHTML = a + "%";
690 var a = YAHOO.widget.DataTable.CLASS_ASC;
691 var d = YAHOO.widget.DataTable.CLASS_DESC;
692 var c = PV.STRINGS.colHeads;
693 var f = formatTimeValue;
696 {key:"fn", sortable:true, label: c.fn[0],
697 sortOptions: {defaultDir:a},
698 resizeable: (YAHOO.util.DragDrop) ? true : false,
700 {key:"calls", sortable:true, label: c.calls[0],
701 sortOptions: {defaultDir:d},
703 {key:"avg", sortable:true, label: c.avg[0],
704 sortOptions: {defaultDir:d},
707 {key:"min", sortable:true, label: c.min[0],
708 sortOptions: {defaultDir:a},
711 {key:"max", sortable:true, label: c.max[0],
712 sortOptions: {defaultDir:d},
715 {key:"total", sortable:true, label: c.total[0],
716 sortOptions: {defaultDir:d},
719 {key:"pct", sortable:true, label: c.pct[0],
720 sortOptions: {defaultDir:d},
721 formatter:formatPercent,
725 this._dataTable = new YAHOO.widget.DataTable(this._tableEl, cols, ds, {
727 height:this.get("tableHeight"),
731 dir: YAHOO.widget.DataTable.CLASS_DESC
734 var dt = this._dataTable;
736 //Wire up DataTable events to drive the rest of the UI.
737 dt.subscribe("sortedByChange", this._sortedByChange, this, true);
738 dt.subscribe("renderEvent", this._dataTableRenderHandler, this, true);
739 dt.subscribe("initEvent", this._dataTableRenderHandler, this, true);
740 Event.on(this._tableEl.getElementsByTagName("th"), "click", this._thClickHandler, this, true);
744 * Proxy the sort event in DataTable into the ProfilerViewer
746 * @method _sortedByChange
749 proto._sortedByChange = function(o) {
750 if(o.newValue && o.newValue.key) {
751 this.set("sortedBy", {key: o.newValue.key, dir:o.newValue.dir});
756 * Proxy the render event in DataTable into the ProfilerViewer
758 * @method _dataTableRenderHandler
761 proto._dataTableRenderHandler = function(o) {
762 this._setBusyState(false);
766 * Event handler for clicks on the DataTable's sortable column
768 * @method _thClickHandler
771 proto._thClickHandler = function(o) {
772 this._setBusyState(true);
776 * Refresh DataTable, getting new data from Profiler.
777 * @method _refreshDataTable
780 proto._refreshDataTable = function(args) {
781 var dt = this._dataTable;
782 dt.getDataSource().sendRequest("", dt.onDataReturnInitializeTable, dt);
786 * Refresh chart, getting new data from table.
787 * @method _refreshChart
790 proto._refreshChart = function() {
792 switch (this.get("sortedBy").key) {
794 /*Keep the same data on the chart, but force update to
795 reflect new sort order on function/method name: */
796 this._chart.set("dataSource", this._chart.get("dataSource"));
797 /*no further action necessary; chart redraws*/
800 /*Null out the xAxis formatting before redrawing chart.*/
801 this._chart.set("xAxis", this._chartAxisDefinitionPlain);
804 this._chart.set("xAxis", this._chartAxisDefinitionPercent);
807 /*Set the default xAxis; redraw legend; set the new series definition.*/
808 this._chart.set("xAxis", this._chartAxisDefinitionTime);
812 this._drawChartLegend();
813 this._chart.set("series", this._getSeriesDef(this.get("sortedBy").key));
818 * Get data for the Chart from DataTable recordset
819 * @method _getChartData
822 proto._getChartData = function() {
823 //var records = this._getProfilerData();
824 var records = this._dataTable.getRecordSet().getRecords(0, this.get("maxChartFunctions"));
826 for (var i = 0, j = records.length; i<j; i++) {
827 arr.push(records[i].getData());
833 * Build series definition based on current configuration attributes.
834 * @method _getSeriesDef
837 proto._getSeriesDef = function(field) {
838 var sd = this.get("chartSeriesDefinitions")[field];
840 for(var i = 0, j = sd.group.length; i<j; i++) {
841 var c = this.get("chartSeriesDefinitions")[sd.group[i]];
843 {displayName:c.displayName,
845 style: {color:c.style.color, size:c.style.size}
858 proto._initChart = function() {
860 this._sizeChartCanvas();
862 YAHOO.widget.Chart.SWFURL = this.get("swfUrl");
866 //Create DataSource based on records currently displayed
867 //at the top of the sort list in the DataTable.
868 var ds = new YAHOO.util.DataSource(
869 //force the jsfunction DataSource to run in the scope of
870 //the ProfilerViewer, not in the YAHOO.util.DataSource scope:
872 return self._getChartData.call(self);
875 responseType: YAHOO.util.DataSource.TYPE_JSARRAY,
882 fields: [ "fn", "avg", "calls", "max", "min", "total", "pct" ]
885 ds.subscribe('responseEvent', this._sizeChartCanvas, this, true);
887 //Set up the chart itself.
888 this._chartAxisDefinitionTime = new YAHOO.widget.NumericAxis();
889 this._chartAxisDefinitionTime.labelFunction = "YAHOO.widget.ProfilerViewer.timeAxisLabelFunction";
891 this._chartAxisDefinitionPercent = new YAHOO.widget.NumericAxis();
892 this._chartAxisDefinitionPercent.labelFunction = "YAHOO.widget.ProfilerViewer.percentAxisLabelFunction";
894 this._chartAxisDefinitionPlain = new YAHOO.widget.NumericAxis();
896 this._chart = new YAHOO.widget.BarChart( this._chartEl, ds,
899 series: this._getSeriesDef(this.get("sortedBy").key),
900 style: this.get("chartStyle"),
901 xAxis: this._chartAxisDefinitionTime
904 this._drawChartLegend();
905 this._chartInitialized = true;
906 this._dataTable.unsubscribe("initEvent", this._initChart, this);
907 this._dataTable.subscribe("initEvent", this._refreshChart, this, true);
912 * Set up the Chart's legend
913 * @method _drawChartLegend
916 proto._drawChartLegend = function() {
917 var seriesDefs = this.get("chartSeriesDefinitions");
918 var currentDef = seriesDefs[this.get("sortedBy").key];
919 var l = this._chartLegendEl;
921 for(var i = 0, j = currentDef.group.length; i<j; i++) {
922 var c = seriesDefs[currentDef.group[i]];
923 var dt = document.createElement("dt");
924 Dom.setStyle(dt, "backgroundColor", "#" + c.style.color);
925 var dd = document.createElement("dd");
926 dd.innerHTML = c.displayName;
933 * Resize the chart's canvas if based on number of records
934 * returned from the chart's datasource.
935 * @method _sizeChartCanvas
938 proto._sizeChartCanvas = function(o) {
939 var bars = (o) ? o.response.length : this.get("maxChartFunctions");
940 var s = (bars * 36) + 34;
941 if (s != parseInt(this._chartElHeight, 10)) {
942 this._chartElHeight = s;
943 Dom.setStyle(this._chartEl, "height", s + "px");
948 * setAttributeConfigs TabView specific properties.
949 * @method initAttributes
950 * @param {Object} attr Hash of initial attributes
951 * @method initAttributes
954 proto.initAttributes = function(attr) {
955 YAHOO.widget.ProfilerViewer.superclass.initAttributes.call(this, attr);
957 * The YUI Loader base path from which to pull YUI files needed
958 * in the rendering of the ProfilerViewer canvas. Passed directly
959 * to YUI Loader. Leave blank to draw files from
965 this.setAttributeConfig('base', {
970 * The height of the DataTable. The table will scroll
971 * vertically if the content overflows the specified
973 * @attribute tableHeight
977 this.setAttributeConfig('tableHeight', {
978 value: attr.tableHeight || "15em",
979 method: function(s) {
980 if(this._dataTable) {
981 this._dataTable.set("height", s);
987 * The default column key to sort by. Valid keys are: fn, calls,
988 * avg, min, max, total. Valid dir values are:
989 * YAHOO.widget.DataTable.CLASS_ASC and
990 * YAHOO.widget.DataTable.CLASS_DESC (or their
991 * string equivalents).
992 * @attribute sortedBy
994 * @default {key:"total", dir:"yui-dt-desc"}
996 this.setAttributeConfig('sortedBy', {
997 value: attr.sortedBy || {key:"total", dir:"yui-dt-desc"}
1001 * A filter function to use in selecting functions that will
1002 * appear in the ProfilerViewer report. The function is passed
1003 * a function report object and should return a boolean indicating
1004 * whether that function should be included in the ProfilerViewer
1005 * display. The argument is structured as follows:
1008 * fn: <str function name>,
1009 * calls : <n number of calls>,
1010 * avg : <n average call duration>,
1011 * max: <n duration of longest call>,
1012 * min: <n duration of shortest call>,
1013 * total: <n total time of all calls>
1014 * points : <array time in ms of each call>
1017 * For example, you would use the follwing filter function to
1018 * return only functions that have been called at least once:
1021 * return (o.calls > 0);
1028 this.setAttributeConfig('filter', {
1029 value: attr.filter || null,
1030 validator: YAHOO.lang.isFunction
1034 * The path to the YUI Charts swf file; must be a full URI
1035 * or a path relative to the page being profiled. Changes at runtime
1036 * not supported; pass this value in at instantiation.
1039 * @default "http://yui.yahooapis.com/2.5.0/build/charts/assets/charts.swf"
1041 this.setAttributeConfig('swfUrl', {
1042 value: attr.swfUrl || "http://yui.yahooapis.com/2.5.0/build/charts/assets/charts.swf"
1046 * The maximum number of functions to profile in the chart. The
1047 * greater the number of functions, the greater the height of the
1050 * @attribute maxChartFunctions
1054 this.setAttributeConfig('maxChartFunctions', {
1055 value: attr.maxChartFunctions || 6,
1056 method: function(s) {
1057 if(this._rendered) {
1058 this._sizeChartCanvas();
1061 validator: YAHOO.lang.isNumber
1065 * The style object that defines the chart's visual presentation.
1066 * Conforms to the style attribute passed to the Charts Control
1067 * constructor. See Charts Control User's Guide for more information
1068 * on how to format this object.
1069 * @attribute chartStyle
1071 * @default See JS source for default definitions.
1073 this.setAttributeConfig('chartStyle', {
1074 value: attr.chartStyle || {
1086 method: function() {
1087 if(this._rendered && this.get("showChart")) {
1088 this._refreshChart();
1094 * The series definition information to use when charting
1095 * specific fields on the chart. "displayName", "xField",
1096 * and "style" members are used to construct the series
1097 * definition; the "group" member is the array of fields
1098 * that should be charted when the table is sorted by a
1099 * given field. The "displayName" string value will be
1100 * treated as markup and inserted into the DOM with innerHTML.
1101 * @attribute chartSeriesDefinitions
1103 * @default See JS source for full default definitions.
1105 this.setAttributeConfig('chartSeriesDefinitions', {
1106 value: attr.chartSeriesDefinitions || {
1108 displayName: PV.STRINGS.colHeads.total[0],
1110 style: {color:"4d95dd", size:20},
1114 displayName: PV.STRINGS.colHeads.calls[0],
1116 style: {color:"edff9f", size:20},
1120 displayName: PV.STRINGS.colHeads.avg[0],
1122 style: {color:"209daf", size:9},
1123 group: ["avg", "min", "max"]
1126 displayName: PV.STRINGS.colHeads.min[0],
1128 style: {color:"b6ecf4", size:9},
1129 group: ["avg", "min", "max"]
1132 displayName: PV.STRINGS.colHeads.max[0],
1134 style: {color:"29c7de", size:9},
1135 group: ["avg", "min", "max"]
1138 displayName: PV.STRINGS.colHeads.pct[0],
1140 style: {color:"C96EDB", size:20},
1144 method: function() {
1145 if(this._rendered && this.get("showChart")) {
1146 this._refreshChart();
1152 * The default visibility setting for the viewer canvas. If true,
1153 * the viewer will load all necessary files and render itself
1154 * immediately upon instantiation; otherwise, the viewer will
1155 * load only minimal resources until the user toggles visibility
1157 * @attribute visible
1161 this.setAttributeConfig('visible', {
1162 value: attr.visible || false,
1163 validator: YAHOO.lang.isBoolean,
1164 method: function(b) {
1168 if (this._rendered) {
1176 * The default visibility setting for the chart.
1177 * @attribute showChart
1181 this.setAttributeConfig('showChart', {
1182 value: attr.showChart || true,
1183 validator: YAHOO.lang.isBoolean,
1188 YAHOO.widget.ProfilerViewer.superclass.initAttributes.call(this, attr);
1194 YAHOO.register("profilerviewer", YAHOO.widget.ProfilerViewer, {version: "2.9.0", build: "2800"});