Type.registerNamespace("Stratman.Web.UI");
/// <summary>
/// Display method to use when rendering a performance counter's data on screen.
/// </summary>
Stratman.Web.UI.PerformanceCounterDisplayType = function() {};
Stratman.Web.UI.PerformanceCounterDisplayType.prototype =
{
/// <summary>
/// Display the current value of the counter.
/// </summary>
Text: 0,
/// <summary>
/// Display a single, updating bar representing the percentage value of the counter between
/// its floor and ceiling.
ProgressBar: 1,
/// <summary>
/// Display a line graph of the counter's historical data.
/// </summary>
LineGraph: 2,
/// <summary>
/// Display a histogram (bar graph) of the counter's historical data.
/// </summary>
Histogram: 3
}
/// <summary>
/// Specifies the direction in which items of a list control are displayed.
/// </summary>
Stratman.Web.UI.PerformanceCounterDisplayType.registerEnum("Stratman.Web.UI.PerformanceCounterDisplayType");
Sys.UI.RepeatDirection = function() {};
Sys.UI.RepeatDirection.prototype =
{
/// <summary>
/// Items of a list are displayed horizontally in rows from left to right, then top to bottom,
/// until all items are rendered.
/// </summary>
Horizontal: 0,
/// <summary>
/// Items of a list are displayed vertically in columns from top to bottom, and then left to
/// right, until all items are rendered.
/// </summary>
Vertical: 1
}
Sys.UI.RepeatDirection.registerEnum("Sys.UI.RepeatDirection");
var refreshHash = new Object();
/// <summary>
/// Constructor for the client-side class that holds information about a performance counter
/// control.
/// </summary>
/// <param name="id">
/// Client ID of the control.
/// </param>
/// <param name="type">
/// Display method to use when rendering the control's data.
/// </param>
/// <param name="value">
/// Initial value for the performance counter.
/// </param>
/// <param name="refreshInterval">
/// Interval, in seconds, between data refresh attempts.
/// </param>
/// <param name="width">
/// Width of the rendered data on screen (not applicable for text display type).
/// </param>
/// <param name="height">
/// Height of the rendered data on screen (not applicable for text display type).
/// </param>
/// <param name="ceiling">
/// Maximum value of this performance counter.
/// </param>
/// <param name="floor">
/// Minimum value of this performance counter.
/// </param>
/// <param name="formatString">
/// JavaScript-compatible format string (String.format()) used to format the value prior to
/// rendering it on screen (applicable only for text display type).
/// </param>
/// <param name="orientation">
/// Direction in which the progress bar should "grow" for progress bar display types.
/// </param>
/// <param name="historyCount">
/// Number of historical values that we are to display for the performance counter (applicable only
/// for histogram and line graph display types).
/// </param>
/// <param name="cssClass">
/// CSS class to apply to the HTML element(s) rendered on the screen.
/// </param>
/// <param name="categoryName">
/// Category name of the counter that we are to render.
/// </param>
/// <param name="counterName">
/// Name of the counter that we are to render.
/// </param>
/// <param name="instanceName">
/// Instance name of the counter that we are to render.
/// </param>
/// <param name="machineName">
/// Name of the machine on which the performance counter resides.
/// </param>
/// <param name="onChange">
/// Client-side JavaScript function that we should call when this control's value is refreshed.
/// </param>
Stratman.Web.UI.PerformanceCounter = function(id, type, value, refreshInterval, width, height, ceiling, floor, formatString, orientation, historyCount, cssClass, categoryName, counterName, instanceName, machineName, onChange)
{
// Initialize the members of the class
this.ID = id;
this.Type = type;
this.Value = value;
this.RefreshInterval = refreshInterval;
this.Width = width;
this.Height = height;
this.Ceiling = ceiling;
this.Floor = floor;
this.FormatString = formatString;
this.Orientation = orientation;
this.HistoryCount = historyCount;
this.CssClass = cssClass;
this.CategoryName = categoryName;
this.CounterName = counterName;
this.InstanceName = instanceName;
this.MachineName = machineName;
this.OnChange = onChange;
this.ChildElementIDs = [];
// Any arguments passed to us after the formal arguments represent the client IDs of child
// elements contained within this control
for (var i = 17; i < arguments.length; i++)
Array.add(this.ChildElementIDs, arguments[i]);
// Perform the initial String.format() on the counter's value for text display controls
if (type == Stratman.Web.UI.PerformanceCounterDisplayType.Text)
this.Render();
// Initialize the historical samples for line graphs and histograms, which require historical
// data
else if (type == Stratman.Web.UI.PerformanceCounterDisplayType.LineGraph || type == Stratman.Web.UI.PerformanceCounterDisplayType.Histogram)
{
this.HistorySamples = [];
for (var i = 0; i < historyCount - 1; i++)
this.HistorySamples[i] = floor;
this.HistorySamples[historyCount - 1] = value;
// For line graphs, initialize the vector graphics library and perform the initial render
if (type == Stratman.Web.UI.PerformanceCounterDisplayType.LineGraph)
{
this.VectorGraphics = new jsGraphics(this.ChildElementIDs[0]);
this.Render();
}
}
// Register the counter for periodic refreshes
if (refreshInterval > 0)
RegisterForRefresh(id, refreshInterval);
}
/// <summary>
/// Updates the CSS class being used for the control.
/// </summary>
/// <param name="cssClass">
/// New CSS class to use for this control.
/// </param>
Stratman.Web.UI.PerformanceCounter.prototype.SetCssClass = function(cssClass)
{
this.CssClass = cssClass;
// For text and progress bar controls, just update the class of the single child element
if (this.Type == Stratman.Web.UI.PerformanceCounterDisplayType.Text || this.Type == Stratman.Web.UI.PerformanceCounterDisplayType.ProgressBar)
document.getElementById(this.ChildElementIDs[0]).className = cssClass;
// For histograms, update the class of each bar
else if (this.Type == Stratman.Web.UI.PerformanceCounterDisplayType.Histogram)
{
for (var i = 0; i < this.ChildElementIDs.length; i++)
document.getElementById(this.ChildElementIDs[i]).className = cssClass;
}
// For line graphs, call Render() so that the vector graphics library can render the graph
else if (this.Type == Stratman.Web.UI.PerformanceCounterDisplayType.LineGraph)
this.Render();
}
/// <summary>
/// Renders the performance counter's data to the screen using the pre-determined display method.
/// </summary>
Stratman.Web.UI.PerformanceCounter.prototype.Render = function()
{
// For text displays, simply call String.format()
if (this.Type == Stratman.Web.UI.PerformanceCounterDisplayType.Text)
document.getElementById(this.ChildElementIDs[0]).innerHTML = String.format(this.FormatString, this.Value);
// For progress bars, just set the width or height (depending on the orientation) of the
// progress bar
else if (this.Type == Stratman.Web.UI.PerformanceCounterDisplayType.ProgressBar)
{
if (this.Orientation == Sys.UI.RepeatDirection.Vertical)
document.getElementById(this.ChildElementIDs[0]).style.height = Math.round(Math.max(Math.min((this.Value - this.Floor) / this.Ceiling, 1) * this.Height, 1)) + "px";
else
document.getElementById(this.ChildElementIDs[0]).style.width = Math.round(Math.max(Math.min((this.Value - this.Floor) / this.Ceiling, 1) * this.Width, 1)) + "px";
}
// For histograms, set the height of each bar to the value of the corresponding entry in the
// history data
else if (this.Type == Stratman.Web.UI.PerformanceCounterDisplayType.Histogram)
{
for (var i = 0; i < this.HistoryCount; i++)
document.getElementById(this.ChildElementIDs[i]).style.height = Math.max(Math.min((this.HistorySamples[i] - this.Floor) / this.Ceiling, 1) * this.Height, 1) + "px";
}
// For line graphs, call the drawLine() function in the vector graphics library for each entry
// in the history data
else if (this.Type == Stratman.Web.UI.PerformanceCounterDisplayType.LineGraph)
{
var sampleWidth = Math.round(this.Width / this.HistoryCount);
var lineHTML = "";
this.VectorGraphics.setCssClass(this.CssClass);
this.VectorGraphics.clear();
for (var i = 0; i < this.HistoryCount - 1; i++)
this.VectorGraphics.drawLine((i * sampleWidth), this.Height - Math.round(Math.min((this.HistorySamples[i] - this.Floor) / this.Ceiling, 1) * (this.Height - 1)) - 1, ((i + 1) * sampleWidth), this.Height - Math.round(Math.min((this.HistorySamples[i + 1] - this.Floor) / this.Ceiling, 1) * (this.Height - 1)) - 1);
this.VectorGraphics.paint();
}
}
/// <summary>
/// Registers a control ID for data refresh at a pre-determined interval; we group all the controls
/// with the same refresh interval together so that we can consolidate the callbacks we make to
/// the web server.
/// </summary>
/// <param name="id">
/// ID of the control that we are to register.
/// </param>
/// <param name="refreshInterval">
/// Interval, in seconds, between data refresh attempts for this control.
/// </param>
function RegisterForRefresh(id, refreshInterval)
{
// Create the refresh hash entry for this interval if it doesn't already exist and make a call
// to setTimeout() to initialize the callback
if (refreshHash[refreshInterval] == null)
{
refreshHash[refreshInterval] = [];
window.setTimeout("UpdatePerformanceCounters(" + refreshInterval + ")", refreshInterval * 1000);
}
Array.add(refreshHash[refreshInterval], id);
}
/// <summary>
/// Makes a callback to the web server to get the updated values for all performance counter
/// controls scheduled to be refreshed at the given interval.
/// </summary>
/// <param name="refreshInterval">
/// Interval that we are refreshing.
/// </param>
function UpdatePerformanceCounters(refreshInterval)
{
// Assemble the list of control IDs to update into a comma-delimited string
var performanceCounterIDs = refreshHash[refreshInterval][0];
for (var i = 1; i < refreshHash[refreshInterval].length; i++)
performanceCounterIDs += "," + refreshHash[refreshInterval][i];
// Make the callback to the web server and call setTimeout() again to re-register this callback
WebForm_DoCallback(refreshHash[refreshInterval][0], performanceCounterIDs, RenderPerformanceCounters, refreshInterval, null, false);
window.setTimeout("UpdatePerformanceCounters(" + refreshInterval + ")", refreshInterval * 1000);
}
/// <summary>
/// Callback function that is invoked when we get a successful response from the web server for a
/// counter value update callback request; updates the values of the applicable controls and re-
/// renders them.
/// </summary>
/// <param name="response">
/// String that was returned from the web server.
/// </param>
/// <param name="context">
/// Context associated with the callback; in this case it's the refresh interval.
/// </param>
function RenderPerformanceCounters(response, context)
{
var performanceCounterValues = response.split(",");
// Loop through each control that we're to update
for (var i = 0; i < performanceCounterValues.length; i++)
{
var performanceCounter = performanceCounters[refreshHash[context][i]];
performanceCounter.Value = Number.parseInvariant(performanceCounterValues[i]);
// Update the history data for line graphs and histograms
if (performanceCounter.Type == Stratman.Web.UI.PerformanceCounterDisplayType.LineGraph || performanceCounter.Type == Stratman.Web.UI.PerformanceCounterDisplayType.Histogram)
{
for (var x = 0; x < performanceCounter.HistoryCount - 1; x++)
performanceCounter.HistorySamples[x] = performanceCounter.HistorySamples[x + 1];
performanceCounter.HistorySamples[performanceCounter.HistoryCount - 1] = performanceCounter.Value;
}
// Render the control
performanceCounter.Render();
// Invoke the value changed event handler, if it's set
if (performanceCounter.OnChange)
performanceCounter.OnChange(performanceCounter);
}
}