[Ovirt-devel] [PATCH server] Add host chart to flexchart.
Steve Linabery
slinabery at redhat.com
Fri Feb 6 05:55:36 UTC 2009
Allow user to select the data function desired (min, peak, avg, rolling averages, etc.).
Add scale to y-axis.
Various changes to the class structure.
---
src/app/controllers/graph_controller.rb | 89 +++++++-
src/app/util/stats/Stats.rb | 20 ++-
src/app/util/stats/StatsDataList.rb | 11 +-
src/app/views/graph/history_graphs.rhtml | 2 +-
src/config/routes.rb | 4 +-
src/flexchart/flexchart.mxml | 33 ++-
src/flexchart/org/ovirt/ApplicationBus.as | 10 +-
src/flexchart/org/ovirt/DataSource.as | 60 -----
src/flexchart/org/ovirt/charts/BarChart.as | 244 ++++++++++++++------
src/flexchart/org/ovirt/charts/Chart.as | 79 +++++--
src/flexchart/org/ovirt/charts/HostChart.as | 177 ++++++++++++++
src/flexchart/org/ovirt/data/BarChartDataSource.as | 42 ++++
src/flexchart/org/ovirt/data/DataPoint.as | 16 ++-
src/flexchart/org/ovirt/data/DataSeries.as | 11 +-
src/flexchart/org/ovirt/data/DataSource.as | 66 ++++++
.../org/ovirt/data/FlexchartDataTransferObject.as | 90 +++++++
.../org/ovirt/data/HostChartDataSource.as | 42 ++++
src/flexchart/org/ovirt/elements/Scale.as | 87 +++++++
src/flexchart/org/ovirt/elements/SingleBar.as | 9 +-
19 files changed, 902 insertions(+), 190 deletions(-)
delete mode 100644 src/flexchart/org/ovirt/DataSource.as
create mode 100644 src/flexchart/org/ovirt/charts/HostChart.as
create mode 100644 src/flexchart/org/ovirt/data/BarChartDataSource.as
create mode 100644 src/flexchart/org/ovirt/data/DataSource.as
create mode 100644 src/flexchart/org/ovirt/data/FlexchartDataTransferObject.as
create mode 100644 src/flexchart/org/ovirt/data/HostChartDataSource.as
create mode 100644 src/flexchart/org/ovirt/elements/Scale.as
diff --git a/src/app/controllers/graph_controller.rb b/src/app/controllers/graph_controller.rb
index e8eea7e..15fa572 100644
--- a/src/app/controllers/graph_controller.rb
+++ b/src/app/controllers/graph_controller.rb
@@ -3,13 +3,14 @@ require 'util/stats/Stats'
class GraphController < ApplicationController
layout nil
+
def flexchart_data
@id = params[:id]
target = params[:target]
startTime = Time.at(params[:startTime].to_i)
endTime = Time.at(params[:endTime].to_i)
duration = endTime.to_i - startTime.to_i
-
+ dataFunction = DEV_KEY_FUNCTIONS[params[:dataFunction]] ? DEV_KEY_FUNCTIONS[params[:dataFunction]] : DEV_KEY_FUNCTIONS['peak']
#the maximum number of data points we want in any chart
maxPoints = 100
resolution =
@@ -51,7 +52,7 @@ class GraphController < ApplicationController
range[0].to_i,
range[1].to_i - range[0].to_i,
resolution,
- DataFunction::Peak)
+ dataFunction)
}
}
statsList = getAggregateStatsData?(requestList)
@@ -62,15 +63,87 @@ class GraphController < ApplicationController
data.each{ |datum|
val = datum.get_value?
val = 0 if (val != 0 && val.nan?)
- vectors.push [datum.get_timestamp?.to_i, val]
+ vectors.push [datum.get_timestamp?.to_i, val, "n/a"]
}
graph = { :vectors => vectors,
:max_value => stat.get_max_value?,
- :description => target
+ :description => target,
+ :resolution => stat.get_resolution?
}
render :json => graph
end
+ def host_chart_data
+ #expect (pool) id, resolution, startTime, target, dataFunction
+ @id = params[:id]
+ resolution = params[:resolution].to_i
+ startTime = Time.at(params[:startTime].to_i)
+ target = params[:target]
+ dataFunction = params[:dataFunction]
+
+ devclass = DEV_KEY_CLASSES[target]
+ counter = DEV_KEY_COUNTERS[target]
+
+
+ pool = Pool.find(@id)
+ hosts = Host.find(:all,
+ :include=> :membership_audit_events,
+ :conditions => ['membership_audit_events.container_target_id = ?',pool])
+
+ requestList = [ ]
+ hosts.each{ |host|
+
+ eventsInRange = host.membership_audit_events.from_pool(pool,
+ startTime,
+ Time.at(startTime.to_i + resolution))
+ excluded = false
+ if eventsInRange.empty?
+ priorAuditEvent = host.membership_audit_events.most_recent_prior_event_from_pool(pool,startTime)
+ if priorAuditEvent.nil? || priorAuditEvent.action == MembershipAuditEvent::LEAVE
+ excluded = true
+ end
+ end
+
+ if (! excluded)
+ requestList.push StatsRequest.new(host.hostname,
+ devclass,
+ 0,
+ counter,
+ startTime.to_i - resolution,
+ resolution,
+ resolution,
+ dataFunction)
+ end
+ }
+
+ statsLists = getStatsData?(requestList)
+ vectors = [ ]
+
+ myMax = 0
+ statsLists.each { |statsList|
+ nodeName = statsList.get_node?.to_s
+ data = statsList.get_data?
+
+ myVal = data[0].get_value?
+ myTime = data[0].get_timestamp?.to_i
+ if myVal.is_a?(Float) && myVal.nan?
+ myVal = 0
+ end
+ myMax = [myMax, myVal].max
+ vectors.push [myTime, myVal, nodeName.to_s]
+ }
+
+
+ graph = { :vectors => vectors,
+ :max_value => myMax,
+ :description => target,
+ :resolution => resolution
+ }
+
+ render :json => graph
+ end
+
+
def get_ranges_from_event_list(list, priorEvent, startTime, endTime)
results = Array.new
@@ -507,6 +580,14 @@ class GraphController < ApplicationController
'load' => LoadCounter::Load_1min, 'netin' => NicCounter::Octets_rx, 'netout' => NicCounter::Octets_tx }
DEV_COUNTER_KEYS = DEV_KEY_COUNTERS.invert
+ DEV_KEY_FUNCTIONS = { 'average' => DataFunction::Average,
+ 'peak' => DataFunction::Peak,
+ 'min' => DataFunction::Min,
+ 'rolling avg' => DataFunction::RollingAverage,
+ 'rolling peak' => DataFunction::RollingPeak,
+ 'rolling min' => DataFunction::RollingMin }
+ DEV_FUNCTION_KEYS = DEV_KEY_FUNCTIONS.invert
+
def _create_host_snapshot_requests(hostname, duration, resolution)
requestList = []
requestList << StatsRequest.new(hostname, DEV_KEY_CLASSES['memory'], 0, DEV_KEY_COUNTERS['memory'],
diff --git a/src/app/util/stats/Stats.rb b/src/app/util/stats/Stats.rb
index f6b0c7a..f7e9dbe 100644
--- a/src/app/util/stats/Stats.rb
+++ b/src/app/util/stats/Stats.rb
@@ -27,6 +27,8 @@ require 'util/stats/StatsRequest'
# This fetches a rolling average, basically average points before and after.
+
+
def fetchRollingAve?(rrdPath, start, endTime, interval, myFunction, lIndex, returnList, aveLen=7)
final = 0
my_min = 0
@@ -255,11 +257,11 @@ def fetchData?(node, devClass, instance, counter, startTime, duration, interval,
sTime = startTime
eTime = sTime + duration
end
-
# Now mangle based on the intervals
start = (sTime / interval).to_i * interval
endTime = (eTime / interval).to_i * interval
+
rrdBase="/var/lib/collectd/rrd/"
rrdNode=rrdBase + node + "/"
@@ -309,7 +311,7 @@ def fetchData?(node, devClass, instance, counter, startTime, duration, interval,
myFunction="AVERAGE"
end
- returnList = StatsDataList.new(node,devClass,instance, counter, localStatus, function)
+ returnList = StatsDataList.new(node,devClass,instance, counter, localStatus, function, interval)
if ( localStatus == StatsStatus::SUCCESS )
if ( function == DataFunction::RollingPeak) ||
@@ -368,14 +370,23 @@ def getAggregateStatsData?(statRequestList)
my_max = 0
value = 0
+ resolution = 0
+
node = "Aggregate"
- returnList = StatsDataList.new("Aggregate",0,0, 0, 0, 0)
+ returnList = StatsDataList.new("Aggregate", 0, 0, 0, 0, 0, 0)
statRequestList.each do |request|
+ #all aggregates need to have the same interval/resolution/precision
+ if resolution == 0
+ resolution = request.get_precision?
+ end
node = request.get_node?
counter = request.get_counter?
tmpList =fetchData?(request.get_node?, request.get_devClass?,request.get_instance?, request.get_counter?, \
request.get_starttime?, request.get_duration?,request.get_precision?, request.get_function?)
-
+ #if the interval/resolution/precision varies, raise an exception
+ if request.get_precision? != resolution
+ raise
+ end
# Now for something completely different...
# The first list back will become our "master"
# Each successive list will be proccesed against the master
@@ -458,6 +469,7 @@ def getAggregateStatsData?(statRequestList)
end
returnList.set_min_value(my_min)
returnList.set_max_value(my_max)
+ returnList.set_resolution(resolution)
myList << returnList
return myList
diff --git a/src/app/util/stats/StatsDataList.rb b/src/app/util/stats/StatsDataList.rb
index a39bcc4..6c71400 100644
--- a/src/app/util/stats/StatsDataList.rb
+++ b/src/app/util/stats/StatsDataList.rb
@@ -20,7 +20,7 @@
#define class StatsData List
class StatsDataList
- def initialize(node,devClass,instance, counter, status, function)
+ def initialize(node, devClass, instance, counter, status, function, resolution)
# Instance variables
@node = node
@devClass = devClass
@@ -31,6 +31,7 @@ class StatsDataList
@function = function
@min_value = 0
@max_value = 0
+ @resolution = 0
end
def get_node?()
@@ -88,4 +89,12 @@ class StatsDataList
def get_max_value?()
return @max_value
end
+
+ def set_resolution(value)
+ @resolution = value
+ end
+
+ def get_resolution?()
+ return @resolution
+ end
end
diff --git a/src/app/views/graph/history_graphs.rhtml b/src/app/views/graph/history_graphs.rhtml
index 97ed67f..9488367 100644
--- a/src/app/views/graph/history_graphs.rhtml
+++ b/src/app/views/graph/history_graphs.rhtml
@@ -10,7 +10,7 @@ $('#flex_history_chart').flash(
height: 300,
wmode: 'transparent',
menu: false,
- flashvars: { flexchart_data: "<%= url_for :controller =>'/graph', :action => 'flexchart_data' %>/<%= @id %>/memory/<%= Time.now.to_i - 60 * 60 * 24 %>/<%= Time.now.to_i %>" }
+ flashvars: { flexchart_data: "<%= url_for :controller =>'/graph', :action => 'flexchart_data' %>/<%= @id %>/memory/<%= Time.now.to_i - 60 * 60 * 24 %>/<%= Time.now.to_i %>/peak" }
},
{ version: 9 }
);
diff --git a/src/config/routes.rb b/src/config/routes.rb
index 168ded5..d286c3f 100644
--- a/src/config/routes.rb
+++ b/src/config/routes.rb
@@ -42,8 +42,8 @@ ActionController::Routing::Routes.draw do |map|
map.connect ':controller/service.wsdl', :action => 'wsdl'
# Install the default route as the lowest priority.
- map.connect 'graph/flexchart_data/:id/:target/:startTime/:endTime', :controller => 'graph', :action => 'flexchart_data'
- map.connect 'graph/flexchart_data/:id/:target/:days', :controller => 'graph', :action => 'flexchart_data'
+ map.connect 'graph/flexchart_data/:id/:target/:startTime/:endTime/:dataFunction', :controller => 'graph', :action => 'flexchart_data'
+ map.connect 'graph/host_chart_data/:id/:target/:startTime/:resolution/:dataFunction', :controller => 'graph', :action => 'host_chart_data'
map.connect ':controller/:action/:id.:format'
map.connect ':controller/:action/:id'
diff --git a/src/flexchart/flexchart.mxml b/src/flexchart/flexchart.mxml
index c4a089f..7a86cd9 100644
--- a/src/flexchart/flexchart.mxml
+++ b/src/flexchart/flexchart.mxml
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
-<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="myInit(); populate(mainChart);" styleName="plain" horizontalScrollPolicy="off" verticalScrollPolicy="off">
+<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="myInit();" styleName="plain" horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:Script>
<![CDATA[
@@ -9,10 +9,9 @@
import org.ovirt.ApplicationBus;
import org.ovirt.charts.Chart;
import org.ovirt.charts.BarChart;
+ import org.ovirt.charts.HostChart;
- private function populate(container:VBox):void {
- var chart:Chart = new BarChart(container, parameters['flexchart_data']);
- chart.load();
+ private function populate(container:Box):void {
}
private var expandHistory:Resize = new Resize();
@@ -23,9 +22,10 @@
private function myInit():void {
+ var bus:ApplicationBus = ApplicationBus.instance();
mainChart.height = Constants.height;
mainChart.width = Constants.width;
- hostsChart.width = Constants.width;
+ hostChart.width = Constants.width;
expandHistory.widthTo = Constants.width;
expandHistory.heightTo = Constants.height;
@@ -37,26 +37,33 @@
expandResources.widthTo = Constants.width;
expandResources.heightTo = Constants.height * .6666;
- expandResources.target = hostsChart;
+ expandResources.target = hostChart;
expandResources.duration = 500;
contractResources.widthTo = Constants.width;
contractResources.heightTo = 0;
- contractResources.target = hostsChart;
+ contractResources.target = hostChart;
contractResources.duration = 500;
- ApplicationBus.instance().barClickAction = zoomIntoSeries;
+ bus.mainChartBarClickAction = zoomIntoSeries;
+ bus.closeHostChart = zoomOutSeries;
+ var mChart:Chart = new BarChart(mainChart, parameters['flexchart_data']);
+ bus.mainChart = mChart as BarChart;
+ mChart.load();
+
+ var hChart:Chart = new HostChart(hostChart);
+ bus.hostChart = hChart as HostChart;
}
private function zoomOutSeries(e:Event):void {
expandHistory.end(); expandHistory.play();
contractResources.end(); contractResources.play();
- hostsChart.visible = false;
+ hostChart.visible = false;
}
private function zoomIntoSeries(e:Event):void {
- hostsChart.visible=true;
+ hostChart.visible=true;
expandResources.end(); expandResources.play();
contractHistory.end(); contractHistory.play();
}
@@ -66,8 +73,8 @@
</mx:Script>
- <mx:VBox id="mainChart" />
- <mx:VBox id="hostsChart" visible="false" opaqueBackground="0x00ff00" click="zoomOutSeries(event)">
- <mx:Text text="This Space Reserved for Drill-down Hosts Chart" />
+ <mx:Box id="mainChart" />
+ <mx:VBox id="hostChart" visible="false" opaqueBackground="0xffffff" click="zoomOutSeries(event)">
+
</mx:VBox>
</mx:Application>
diff --git a/src/flexchart/org/ovirt/ApplicationBus.as b/src/flexchart/org/ovirt/ApplicationBus.as
index 7d6d431..24474b9 100644
--- a/src/flexchart/org/ovirt/ApplicationBus.as
+++ b/src/flexchart/org/ovirt/ApplicationBus.as
@@ -22,6 +22,10 @@
//our ActionScript classes without needing to access Application directly
package org.ovirt {
+
+ import org.ovirt.charts.BarChart;
+ import org.ovirt.charts.HostChart;
+
public class ApplicationBus {
private static var _instance:ApplicationBus;
@@ -33,7 +37,11 @@ package org.ovirt {
return _instance;
}
- public var barClickAction:Function;
+ public var mainChartBarClickAction:Function;
+ public var closeHostChart:Function;
+
+ public var mainChart:BarChart;
+ public var hostChart:HostChart;
}
}
diff --git a/src/flexchart/org/ovirt/DataSource.as b/src/flexchart/org/ovirt/DataSource.as
deleted file mode 100644
index 4438900..0000000
--- a/src/flexchart/org/ovirt/DataSource.as
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- Copyright (C) 2008 Red Hat, Inc.
- Written by Steve Linabery <slinabery at redhat.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301, USA. A copy of the GNU General Public License is
- also available at http://www.gnu.org/copyleft/gpl.html.
-*/
-
-package org.ovirt {
-
- import com.adobe.serialization.json.JSON;
- import flash.events.Event;
- import flash.events.IOErrorEvent;
- import flash.net.URLLoader;
- import flash.net.URLRequest;
- import org.ovirt.charts.Chart;
- import org.ovirt.data.DataSeries;
-
- public class DataSource {
-
- private var chart:Chart;
-
- public function DataSource(chart:Chart) {
- this.chart = chart;
- }
-
- public function retrieveData(url:String):void {
- var loader:URLLoader = new URLLoader();
- loader.addEventListener(IOErrorEvent.IO_ERROR, this.ioError);
- loader.addEventListener(Event.COMPLETE, dataLoaded);
- var request:URLRequest = new URLRequest(url);
- loader.load(request);
- }
-
- private function dataLoaded(event:Event):void {
- var loader:URLLoader = URLLoader(event.target);
- var object:Object = JSON.decode(loader.data);
- var series:DataSeries = new DataSeries(object);
- chart.addData(series);
- }
-
- private function ioError( e:IOErrorEvent ):void {
- trace("ioError");
- //FIXME:
- //do something useful with this error
- }
- }
-}
diff --git a/src/flexchart/org/ovirt/charts/BarChart.as b/src/flexchart/org/ovirt/charts/BarChart.as
index 88a75ca..08710d2 100644
--- a/src/flexchart/org/ovirt/charts/BarChart.as
+++ b/src/flexchart/org/ovirt/charts/BarChart.as
@@ -37,9 +37,12 @@ package org.ovirt.charts {
import org.ovirt.elements.*;
import org.ovirt.Constants;
import org.ovirt.ApplicationBus;
+ import mx.core.ScrollPolicy;
public class BarChart extends Chart {
+ private var yScale:Scale;
+ private var chartFrame:HBox;
private var chartArea:Canvas;
private var XAxisLabelArea:Canvas;
private var startDateField:DateField;
@@ -48,18 +51,13 @@ package org.ovirt.charts {
private var endTimeField:TextInput;
private var button:Button;
private var menu:PopUpMenuButton;
+ private var functionMenu:PopUpMenuButton;
private var dateBar:Box;
private var datePattern:RegExp;
-
- public function BarChart(container:Box,
- datasourceUrl:String) {
- super(container,datasourceUrl);
- container.setStyle("verticalGap","2");
- datePattern = /^(\d+):(\d+)$/;
- }
-
-
+ /*
+ Private, class-specific functions
+ */
private function timeRangeAdjusted(event:Event):void {
var t1:Number = startDateField.selectedDate.getTime()
+ (parseHour(startTimeField.text) * 3600 * 1000)
@@ -69,14 +67,34 @@ package org.ovirt.charts {
+ (parseHour(endTimeField.text) * 3600 * 1000)
+ (parseMinute(endTimeField.text) * 60 * 1000);
setEndTime(Math.floor(t2 / 1000));
+
+ //close the host chart when updating top chart
+ ApplicationBus.instance().closeHostChart.call(null,event);
load();
}
+
+ private function updateHostChart(event:MouseEvent):void {
+ var hostChart:HostChart = ApplicationBus.instance().hostChart;
+ hostChart.setId(id);
+ hostChart.setTarget(target);
+ hostChart.setStartTime((event.target as SingleBar).getStartTime() / 1000);
+ hostChart.setResolution((event.target as SingleBar).getResolution());
+ hostChart.setDataFunction(dataFunction);
+ hostChart.load();
+ }
+
private function typeSelected(event:MenuEvent):void {
target = event.label;
+ ApplicationBus.instance().closeHostChart.call(null,event);
load();
}
+ private function functionSelected(event:MenuEvent):void {
+ dataFunction = event.label;
+ ApplicationBus.instance().closeHostChart.call(null,event);
+ load();
+ }
private function pad(input:int):String {
if (input < 10) {
@@ -108,6 +126,32 @@ package org.ovirt.charts {
return answer;
}
+
+ /*
+ Constructors
+ */
+ public function BarChart(container:Box,
+ datasourceUrl:String) {
+ super(container,datasourceUrl);
+ container.setStyle("verticalGap","2");
+ datePattern = /^(\d+):(\d+)$/;
+ }
+
+ /*
+ Overriden functions
+ */
+ override protected function initializeDataSource():void {
+ dataSource = new BarChartDataSource(this);
+ }
+
+ override protected function setRequestAttributes(dto:FlexchartDataTransferObject):void {
+ dto.setId(id);
+ dto.setTarget(target);
+ dto.setStartTime(startTime);
+ dto.setEndTime(endTime);
+ dto.setDataFunction(dataFunction);
+ }
+
override public function addData(dataSeries:DataSeries):void {
container.removeAllChildren();
@@ -123,11 +167,30 @@ package org.ovirt.charts {
}
}
+
+ var yLabelPercentWidth:int = 8;
+
+ chartFrame = new HBox();
+ chartFrame.percentHeight = 80;
+ chartFrame.percentWidth = 100;
+ chartFrame.setVisible(true);
+ chartFrame.setStyle("horizontalGap","1");
+
+ yScale = new Scale();
+ yScale.percentHeight = 100;
+ yScale.percentWidth = yLabelPercentWidth;
+ yScale.setVisible(true);
+
chartArea = new Canvas();
- chartArea.percentHeight = 80;
- chartArea.percentWidth = 100;
+ chartArea.percentHeight = 100;
+ chartArea.percentWidth = 100 - yLabelPercentWidth;
chartArea.setStyle("backgroundColor","0xbbccdd");
- this.container.addChild(chartArea);
+
+ chartArea.verticalScrollPolicy = ScrollPolicy.OFF
+
+ chartFrame.addChild(yScale);
+ chartFrame.addChild(chartArea);
+ this.container.addChild(chartFrame);
XAxisLabelArea = new Canvas();
XAxisLabelArea.height = Constants.labelHeight;
@@ -135,6 +198,9 @@ package org.ovirt.charts {
XAxisLabelArea.percentWidth = 100;
this.container.addChild(XAxisLabelArea);
+ var t1:Date = new Date(startTime * 1000);
+ var t2:Date = new Date(endTime * 1000);
+
try {
dateBar = new HBox();
@@ -143,6 +209,7 @@ package org.ovirt.charts {
var dataPoints:Array = dataSeries.getDataPoints();
var maxValue:Number = dataSeries.getMaxValue();
var scale:Number = maxValue;
+ yScale.setMax(maxValue);
//avoid divide by zero
if (scale == 0) {
scale = 1;
@@ -152,8 +219,10 @@ package org.ovirt.charts {
throw new Error("No data points in range");
}
+ var calculatedWidth:Number = Constants.width * (chartArea.percentWidth / 100.0) ;
+
//the distance between left edges of adjacent bars
- var gridWidth:Number = Math.floor(Constants.width / size);
+ var gridWidth:Number = Math.floor(calculatedWidth / size);
//the width of each SingleBar (does not including padding between bars)
var barWidth:Number = gridWidth - Constants.barSpacing;
@@ -161,7 +230,7 @@ package org.ovirt.charts {
//due to the discrete number of pixels, there may be space at the
//right side of the graph that needs to be made up by padding
//bars here and there
- var shortfall:Number = Constants.width - (gridWidth * size);
+ var shortfall:Number = calculatedWidth - (gridWidth * size);
var makeup:Number = Math.round(size / shortfall);
var madeup:Number = 0;
@@ -196,7 +265,9 @@ package org.ovirt.charts {
chartArea.addChild(bar);
bar.width = barWidth;
bar.addEventListener(MouseEvent.CLICK,
- ApplicationBus.instance().barClickAction);
+ ApplicationBus.instance().mainChartBarClickAction);
+ bar.addEventListener(MouseEvent.CLICK,
+ updateHostChart);
bar.x = currentBarPosition;
if (makeup > 0 && i % makeup == 0 && madeup < shortfall) {
bar.width = bar.width + 1;
@@ -214,7 +285,7 @@ package org.ovirt.charts {
|| i == size - 1) {
var label:XAxisLabel =
new XAxisLabel(dateFormat.format(dataPoint.getTimestamp()));
- label.setCenter(currentBarPosition + bar.width / 2);
+ label.setCenter(currentBarPosition + bar.width / 2 + Constants.width - calculatedWidth);
label.setVisible(true);
label.y = 6;
XAxisLabelArea.addChild(label);
@@ -235,69 +306,90 @@ package org.ovirt.charts {
currentBarPosition += (bar.width + Constants.barSpacing);
}
- //fill in the time range selection bar
- var t:Date;
- var f1:Text = new Text();
- f1.text = "View data between";
- dateBar.addChild(f1);
- t = new Date(dataPoints[0].getTimestamp().getTime());
- startDateField = new DateField();
- startDateField.selectedDate = t;
- startDateField.editable = true;
- startTimeField = new TextInput();
- startTimeField.minWidth = 50;
- startTimeField.maxWidth = 50;
- startTimeField.text = pad(t.hours) + ":" + pad(t.minutes);
- dateBar.addChild(startTimeField);
- dateBar.addChild(startDateField);
- var f2:Text = new Text();
- f2.text = "and";
- dateBar.addChild(f2);
-
- t = new Date(dataPoints[size - 1].getTimestamp().getTime());
- endDateField = new DateField();
- endDateField.selectedDate = t;
- endDateField.editable = true;
- endTimeField = new TextInput();
- endTimeField.minWidth = 50;
- endTimeField.maxWidth = 50;
- endTimeField.text = pad(t.hours) + ":" + pad(t.minutes);
- dateBar.addChild(endTimeField);
- dateBar.addChild(endDateField);
-
- button = new Button();
- button.label = "go";
- button.addEventListener(MouseEvent.CLICK,timeRangeAdjusted);
- dateBar.addChild(button);
-
- //FIXME: these should be fetched from the graph controller so
- //that different types can be added (or restricted) dynamically
- var menuItems:ArrayCollection =
- new ArrayCollection( [{label: "memory"},
- {label: "cpu"},
- {label: "load"},
- {label: "netin"},
- {label: "netout"},
- {label: "disk"}
- ]);
-
-
- if (menu != null) {
- menu.removeEventListener(MenuEvent.ITEM_CLICK,typeSelected);
- }
-
- menu = new PopUpMenuButton();
- menu.label = "Select Data Type";
- menu.dataProvider = menuItems;
- menu.addEventListener(MenuEvent.ITEM_CLICK,typeSelected);
- dateBar.addChild(menu);
+ t1 = new Date(dataPoints[0].getTimestamp().getTime());
+ t2 = new Date(dataPoints[size - 1].getTimestamp().getTime());
} catch (e:Error) {
- var err:Text = new Text();
- err.text = e.message;
- err.setVisible(true);
- chartArea.addChild(err);
+ trace(e.message);
+ }
+
+ //fill in the time range selection bar
+
+ var f1:Text = new Text();
+ f1.text = "View data between";
+ dateBar.addChild(f1);
+
+ startDateField = new DateField();
+ startDateField.selectedDate = t1;
+ startDateField.editable = true;
+ startTimeField = new TextInput();
+ startTimeField.minWidth = 50;
+ startTimeField.maxWidth = 50;
+ startTimeField.text = pad(t1.hours) + ":" + pad(t1.minutes);
+ dateBar.addChild(startTimeField);
+ dateBar.addChild(startDateField);
+ var f2:Text = new Text();
+ f2.text = "and";
+ dateBar.addChild(f2);
+
+
+ endDateField = new DateField();
+ endDateField.selectedDate = t2;
+ endDateField.editable = true;
+ endTimeField = new TextInput();
+ endTimeField.minWidth = 50;
+ endTimeField.maxWidth = 50;
+ endTimeField.text = pad(t2.hours) + ":" + pad(t2.minutes);
+ dateBar.addChild(endTimeField);
+ dateBar.addChild(endDateField);
+
+ button = new Button();
+ button.label = "go";
+ button.addEventListener(MouseEvent.CLICK,timeRangeAdjusted);
+
+ dateBar.addChild(button);
+
+ //FIXME: these should be fetched from the graph controller so
+ //that different types can be added (or restricted) dynamically
+ var menuItems:ArrayCollection =
+ new ArrayCollection( [{label: "memory"},
+ {label: "cpu"},
+ {label: "load"},
+ {label: "netin"},
+ {label: "netout"},
+ {label: "disk"}
+ ]);
+
+ if (menu != null) {
+ menu.removeEventListener(MenuEvent.ITEM_CLICK,typeSelected);
}
+
+ menu = new PopUpMenuButton();
+ menu.label = "Data Type";
+ menu.dataProvider = menuItems;
+ menu.addEventListener(MenuEvent.ITEM_CLICK,typeSelected);
+ dateBar.addChild(menu);
+
+
+ var functionMenuItems:ArrayCollection =
+ new ArrayCollection( [{label: "average"},
+ {label: "peak"},
+ {label: "min"},
+ {label: "rolling avg"},
+ {label: "rolling peak"},
+ {label: "rolling min"}
+ ]);
+
+ if (functionMenu != null) {
+ functionMenu.removeEventListener(MenuEvent.ITEM_CLICK,functionSelected);
+ }
+
+ functionMenu = new PopUpMenuButton();
+ functionMenu.label = "Fn Type";
+ functionMenu.dataProvider = functionMenuItems;
+ functionMenu.addEventListener(MenuEvent.ITEM_CLICK,functionSelected);
+ dateBar.addChild(functionMenu);
+
}
}
}
diff --git a/src/flexchart/org/ovirt/charts/Chart.as b/src/flexchart/org/ovirt/charts/Chart.as
index f2faf33..ee6992e 100644
--- a/src/flexchart/org/ovirt/charts/Chart.as
+++ b/src/flexchart/org/ovirt/charts/Chart.as
@@ -19,58 +19,87 @@
*/
package org.ovirt.charts {
- import org.ovirt.DataSource;
- import mx.containers.Box;
- import org.ovirt.data.DataSeries;
+ import org.ovirt.data.DataSource;
+ import mx.containers.Box;
+ import org.ovirt.data.DataSeries;
+ import org.ovirt.data.FlexchartDataTransferObject;
public class Chart {
protected var container:Box;
- protected var datasourceUrl:String;
+ protected var dataSource:DataSource;
protected var startTime:Number;
protected var endTime:Number;
protected var target:String;
protected var id:int;
+ protected var dataFunction:String;
+ protected var resolution:int;
+ /*
+ Inheritable functions that generally do not need overrides
+ */
+ public function setStartTime(startTime:Number):void {
+ this.startTime = startTime;
+ }
+
+ public function setEndTime(endTime:Number):void {
+ this.endTime = endTime;
+ }
+
+ public function setTarget(target:String):void {
+ this.target = target;
+ }
+
+ public function setId(id:int):void {
+ this.id = id;
+ }
+
+ public function setDataFunction(dataFunction:String):void {
+ this.dataFunction = dataFunction;
+ }
+
+ public function setResolution(resolution:int):void {
+ this.resolution = resolution;
+ }
+
+ public function load():void {
+ var dto:FlexchartDataTransferObject = new FlexchartDataTransferObject();
+ setRequestAttributes(dto);
+ dataSource.retrieveData(dto);
+ }
+
+ /*
+ Constructors
+ */
public function Chart(container:Box, datasourceUrl:String) {
this.container = container;
- this.datasourceUrl = datasourceUrl;
+ initializeDataSource();
if (datasourceUrl != null) {
var results:Array = datasourceUrl.split("/");
- if (results != null && results.length > 7) {
+ if (results != null && results.length > 8) {
setId(new int(results[4]));
setTarget(results[5] as String);
setStartTime(new int(results[6]));
setEndTime(new int(results[7]));
+ setDataFunction(results[8] as String);
}
}
}
- public function addData(dataSeries:DataSeries):void {
- //override me!
- }
-
- public function load():void {
- var dataSource:DataSource = new DataSource(this);
- var myString:String = "/ovirt/graph/flexchart_data/" + id + "/" + target + "/" + startTime + "/" + endTime;
- dataSource.retrieveData(myString);
+ /*
+ Functions that subclasses should override
+ (ActionScript does not offer abstract methods)
+ */
+ protected function initializeDataSource():void {
}
- public function setStartTime(startTime:Number):void {
- this.startTime = startTime;
+ //subclasses should override this
+ protected function setRequestAttributes(dto:FlexchartDataTransferObject):void {
}
- public function setEndTime(endTime:Number):void {
- this.endTime = endTime;
- }
-
- public function setTarget(target:String):void {
- this.target = target;
+ public function addData(dataSeries:DataSeries):void {
}
- public function setId(id:int):void {
- this.id = id;
- }
}
}
diff --git a/src/flexchart/org/ovirt/charts/HostChart.as b/src/flexchart/org/ovirt/charts/HostChart.as
new file mode 100644
index 0000000..ad46236
--- /dev/null
+++ b/src/flexchart/org/ovirt/charts/HostChart.as
@@ -0,0 +1,177 @@
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+ Written by Steve Linabery <slinabery at redhat.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. A copy of the GNU General Public License is
+ also available at http://www.gnu.org/copyleft/gpl.html.
+*/
+
+package org.ovirt.charts {
+ import flash.events.Event;
+ import flash.events.MouseEvent;
+ import mx.collections.ArrayCollection;
+ import mx.containers.Box;
+ import mx.containers.HBox;
+ import mx.containers.VBox;
+ import mx.containers.Canvas;
+ import mx.controls.TextInput;
+ import mx.controls.DateField;
+ import mx.controls.Button;
+ import mx.controls.PopUpMenuButton;
+ import mx.controls.Text;
+ import mx.events.MenuEvent;
+ import mx.formatters.DateFormatter;
+ import org.ovirt.data.*;
+ import org.ovirt.elements.*;
+ import org.ovirt.Constants;
+ import org.ovirt.ApplicationBus;
+ import mx.core.ScrollPolicy;
+
+ public class HostChart extends Chart {
+
+ private var yScale:Scale;
+ private var chartFrame:HBox;
+ private var chartArea:Canvas;
+ private var XAxisLabelArea:Canvas;
+
+ /*
+ Constructors
+ */
+ public function HostChart(container:Box) {
+ super(container,null);
+ }
+
+ /*
+ Overriden functions
+ */
+ override protected function initializeDataSource():void {
+ dataSource = new HostChartDataSource(this);
+ }
+
+ override protected function setRequestAttributes(dto:FlexchartDataTransferObject):void {
+ dto.setId(id);
+ dto.setTarget(target);
+ dto.setStartTime(startTime);
+ dto.setResolution(resolution);
+ dto.setDataFunction(dataFunction);
+ }
+
+ override public function addData(dataSeries:DataSeries):void {
+ container.removeAllChildren();
+
+ var i:int;
+ var yLabelPercentWidth:int = 8;
+
+ chartFrame = new HBox();
+ chartFrame.percentHeight = 80;
+ chartFrame.percentWidth = 100;
+ chartFrame.setVisible(true);
+ chartFrame.setStyle("horizontalGap","1");
+
+ yScale = new Scale();
+ yScale.percentHeight = 100;
+ yScale.percentWidth = yLabelPercentWidth;
+ yScale.setVisible(true);
+
+ chartArea = new Canvas();
+ chartArea.percentHeight = 100;
+ chartArea.percentWidth = 100 - yLabelPercentWidth;
+ chartArea.setStyle("backgroundColor","0xbbccdd");
+
+ chartArea.verticalScrollPolicy = ScrollPolicy.OFF
+
+ chartFrame.addChild(yScale);
+ chartFrame.addChild(chartArea);
+ this.container.addChild(chartFrame);
+
+ XAxisLabelArea = new Canvas();
+ XAxisLabelArea.height = Constants.labelHeight;
+ XAxisLabelArea.minHeight = Constants.labelHeight;
+ XAxisLabelArea.percentWidth = 100;
+ this.container.addChild(XAxisLabelArea);
+
+ try {
+ var dataPoints:Array = dataSeries.getDataPoints();
+ var size:int = dataPoints.length;
+ if (size == 0) {
+ throw new Error("No data points in range");
+ }
+
+ var maxValue:Number = dataSeries.getMaxValue();
+ var scale:Number = maxValue;
+ yScale.setMax(maxValue);
+ //avoid divide by zero
+ if (scale == 0) {
+ scale = 1;
+ }
+
+ var calculatedWidth:Number = Constants.width * (chartArea.percentWidth / 100.0) ;
+
+ //the distance between left edges of adjacent bars
+ var gridWidth:Number = Math.floor(calculatedWidth / size);
+
+ //the width of each SingleBar (does not including padding between bars)
+ var barWidth:Number = gridWidth - Constants.barSpacing;
+
+ //due to the discrete number of pixels, there may be space at the
+ //right side of the graph that needs to be made up by padding
+ //bars here and there
+ var shortfall:Number = calculatedWidth - (gridWidth * size);
+ var makeup:Number = Math.round(size / shortfall);
+ var madeup:Number = 0;
+
+ //variable to hold the x-coordinate of the next bar to be added to
+ //the chart
+ var currentBarPosition:int = 0;
+
+ //add the bars & labels to the chart
+ var labelCounter:int = 0;
+ for (i = 0; i < size; i++) {
+
+ var dataPoint:DataPoint = dataPoints[i] as DataPoint;
+
+ var bar:SingleBar = new SingleBar(dataPoint,scale);
+ chartArea.addChild(bar);
+ bar.width = barWidth;
+ bar.x = currentBarPosition;
+ if (makeup > 0 && i % makeup == 0 && madeup < shortfall) {
+ bar.width = bar.width + 1;
+ madeup++;
+ }
+
+ //if there aren't many bars, make them thinner.
+ if (size < 4) {
+ var tempWidth:Number = bar.width;
+ var tempX:Number = bar.x;
+
+ bar.width = bar.width * .8;
+ bar.x = tempX + tempWidth * .1;
+ }
+
+
+ var label:XAxisLabel =
+ new XAxisLabel(dataPoint.getNodeName());
+ label.setCenter(bar.x + bar.width / 2);
+ label.setVisible(true);
+ label.y = 6;
+ XAxisLabelArea.addChild(label);
+ currentBarPosition += (bar.width + Constants.barSpacing);
+ }
+ } catch (e:Error) {
+ trace(e.getStackTrace())
+ }
+ }
+ }
+}
diff --git a/src/flexchart/org/ovirt/data/BarChartDataSource.as b/src/flexchart/org/ovirt/data/BarChartDataSource.as
new file mode 100644
index 0000000..69e12b1
--- /dev/null
+++ b/src/flexchart/org/ovirt/data/BarChartDataSource.as
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+ Written by Steve Linabery <slinabery at redhat.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. A copy of the GNU General Public License is
+ also available at http://www.gnu.org/copyleft/gpl.html.
+*/
+
+package org.ovirt.data {
+
+ import org.ovirt.charts.Chart;
+
+ public class BarChartDataSource extends DataSource {
+
+ public function BarChartDataSource(chart:Chart) {
+ super(chart);
+ }
+
+ override protected function getUrl(dto:FlexchartDataTransferObject):String {
+ var answer:String = "/ovirt/graph/flexchart_data/" + dto.getId() +
+ "/" + dto.getTarget() +
+ "/" + dto.getStartTime() +
+ "/" + dto.getEndTime() +
+ "/" + dto.getDataFunction();
+ return answer;
+ }
+
+ }
+
+}
diff --git a/src/flexchart/org/ovirt/data/DataPoint.as b/src/flexchart/org/ovirt/data/DataPoint.as
index 5d59de9..8b846e9 100644
--- a/src/flexchart/org/ovirt/data/DataPoint.as
+++ b/src/flexchart/org/ovirt/data/DataPoint.as
@@ -25,12 +25,17 @@ package org.ovirt.data {
private var timestamp:Date;
private var value:Number;
private var description:String;
+ private var resolution:int;
+ private var nodeName:String;
public function DataPoint (timestamp:Date, value:Number,
- description:String) {
+ description:String, resolution:int,
+ nodeName:String) {
this.timestamp = timestamp;
this.value = value;
this.description = description;
+ this.resolution = resolution;
+ this.nodeName = nodeName;
}
public function getTimestamp():Date {
@@ -44,5 +49,14 @@ package org.ovirt.data {
public function getDescription():String {
return description;
}
+
+ public function getResolution():int {
+ return resolution;
+ }
+
+ public function getNodeName():String {
+ return nodeName;
+ }
+
}
}
diff --git a/src/flexchart/org/ovirt/data/DataSeries.as b/src/flexchart/org/ovirt/data/DataSeries.as
index 709ceea..21db100 100644
--- a/src/flexchart/org/ovirt/data/DataSeries.as
+++ b/src/flexchart/org/ovirt/data/DataSeries.as
@@ -35,6 +35,8 @@ package org.ovirt.data {
this.description = object["description"] as String;
dataPoints = new Array();
var inDataPoints:Array = object["vectors"] as Array;
+ var resolution:Number = object["resolution"] as Number;
+
for (var i:int = 0; i < inDataPoints.length; i++) {
var value:Number = 0;
var valuea:Number = (inDataPoints[i] as Array)[1] as Number;
@@ -42,11 +44,17 @@ package org.ovirt.data {
value = (inDataPoints[i] as Array)[1] as Number;
}
var seconds:Number = new Number((inDataPoints[i] as Array)[0]) * 1000;
+ var nodeName:String = (inDataPoints[i] as Array)[2] as String;
+
dataPoints.push(new DataPoint(new Date(seconds),
value,
- description));
+ description,
+ resolution,
+ nodeName));
+
}
maxValue = object["max_value"] as Number;
+
}
public function getDataPoints():Array {
@@ -56,5 +64,6 @@ package org.ovirt.data {
public function getMaxValue():Number {
return maxValue;
}
+
}
}
diff --git a/src/flexchart/org/ovirt/data/DataSource.as b/src/flexchart/org/ovirt/data/DataSource.as
new file mode 100644
index 0000000..4fdd8e8
--- /dev/null
+++ b/src/flexchart/org/ovirt/data/DataSource.as
@@ -0,0 +1,66 @@
+/*
+ Copyright (C) 2008 Red Hat, Inc.
+ Written by Steve Linabery <slinabery at redhat.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. A copy of the GNU General Public License is
+ also available at http://www.gnu.org/copyleft/gpl.html.
+*/
+
+package org.ovirt.data {
+
+ import com.adobe.serialization.json.JSON;
+ import flash.events.Event;
+ import flash.events.IOErrorEvent;
+ import flash.net.URLLoader;
+ import flash.net.URLRequest;
+ import org.ovirt.charts.Chart;
+ import org.ovirt.data.DataSeries;
+
+ public class DataSource {
+
+ private var chart:Chart;
+
+ public function DataSource(chart:Chart) {
+ this.chart = chart;
+ }
+
+ public function retrieveData(dto:FlexchartDataTransferObject):void {
+ var loader:URLLoader = new URLLoader();
+ loader.addEventListener(IOErrorEvent.IO_ERROR, this.ioError);
+ loader.addEventListener(Event.COMPLETE, dataLoaded);
+ var request:URLRequest = new URLRequest(getUrl(dto));
+ loader.load(request);
+ }
+
+ private function dataLoaded(event:Event):void {
+ var loader:URLLoader = URLLoader(event.target);
+ var object:Object = JSON.decode(loader.data);
+ var series:DataSeries = new DataSeries(object);
+ chart.addData(series);
+ }
+
+ private function ioError( e:IOErrorEvent ):void {
+ trace("ioError");
+ //FIXME:
+ //do something useful with this error
+ }
+
+ //subclasses should override
+ protected function getUrl(dto:FlexchartDataTransferObject):String {
+ return null;
+ }
+
+ }
+}
diff --git a/src/flexchart/org/ovirt/data/FlexchartDataTransferObject.as b/src/flexchart/org/ovirt/data/FlexchartDataTransferObject.as
new file mode 100644
index 0000000..8534501
--- /dev/null
+++ b/src/flexchart/org/ovirt/data/FlexchartDataTransferObject.as
@@ -0,0 +1,90 @@
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+ Written by Steve Linabery <slinabery at redhat.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. A copy of the GNU General Public License is
+ also available at http://www.gnu.org/copyleft/gpl.html.
+*/
+
+package org.ovirt.data {
+
+ public class FlexchartDataTransferObject {
+
+ private var startTime:int;
+ private var endTime:int;
+ private var id:int;
+ private var target:String;
+ private var resolution:int;
+ private var averageLength:int;
+ private var dataFunction:String;
+
+ public function setStartTime(startTime:int):void {
+ this.startTime = startTime;
+ }
+
+ public function getStartTime():int {
+ return startTime;
+ }
+
+ public function setEndTime(endTime:int):void {
+ this.endTime = endTime;
+ }
+
+ public function getEndTime():int {
+ return endTime;
+ }
+
+ public function setId(id:int):void {
+ this.id = id;
+ }
+
+ public function getId():int {
+ return id;
+ }
+
+ public function setTarget(target:String):void {
+ this.target = target;
+ }
+
+ public function getTarget():String {
+ return target;
+ }
+
+ public function setResolution(resolution:int):void {
+ this.resolution = resolution;
+ }
+
+ public function getResolution():int {
+ return resolution;
+ }
+
+ public function setAverageLength(averageLength:int):void {
+ this.averageLength = averageLength;
+ }
+
+ public function getAverageLength():int {
+ return averageLength;
+ }
+
+ public function setDataFunction(dataFunction:String):void {
+ this.dataFunction = dataFunction;
+ }
+
+ public function getDataFunction():String {
+ return dataFunction;
+ }
+
+ }
+}
diff --git a/src/flexchart/org/ovirt/data/HostChartDataSource.as b/src/flexchart/org/ovirt/data/HostChartDataSource.as
new file mode 100644
index 0000000..7b36aec
--- /dev/null
+++ b/src/flexchart/org/ovirt/data/HostChartDataSource.as
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+ Written by Steve Linabery <slinabery at redhat.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. A copy of the GNU General Public License is
+ also available at http://www.gnu.org/copyleft/gpl.html.
+*/
+
+package org.ovirt.data {
+
+ import org.ovirt.charts.Chart;
+
+ public class HostChartDataSource extends DataSource {
+
+ public function HostChartDataSource(chart:Chart) {
+ super(chart);
+ }
+
+ override protected function getUrl(dto:FlexchartDataTransferObject):String {
+ var answer:String = "/ovirt/graph/host_chart_data/" + dto.getId() +
+ "/" + dto.getTarget() +
+ "/" + dto.getStartTime() +
+ "/" + dto.getResolution() +
+ "/" + dto.getDataFunction();
+ return answer;
+ }
+
+ }
+
+}
diff --git a/src/flexchart/org/ovirt/elements/Scale.as b/src/flexchart/org/ovirt/elements/Scale.as
new file mode 100644
index 0000000..0238172
--- /dev/null
+++ b/src/flexchart/org/ovirt/elements/Scale.as
@@ -0,0 +1,87 @@
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+ Written by Steve Linabery <slinabery at redhat.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. A copy of the GNU General Public License is
+ also available at http://www.gnu.org/copyleft/gpl.html.
+*/
+
+//an object that calculates/displays tickmarks for axis scales.
+
+package org.ovirt.elements {
+ import mx.containers.Box;
+ import flash.events.Event;
+ import mx.events.FlexEvent;
+ import mx.events.ResizeEvent;
+ import mx.controls.Label;
+
+ public class Scale extends Box {
+
+ private var max:Number;
+ private var maxLabel:Label;
+ private var midLabel:Label;
+
+ public function Scale() {
+ super();
+ opaqueBackground = 0xffffff;
+ max = 0;
+ addEventListener(ResizeEvent.RESIZE,myResize);
+ addEventListener(FlexEvent.CREATION_COMPLETE,myResize);
+ addEventListener(Event.RENDER,myResize);
+ addEventListener(FlexEvent.INITIALIZE,myResize);
+ addEventListener(FlexEvent.UPDATE_COMPLETE,myResize);
+
+ maxLabel = new Label();
+ this.addChild(maxLabel);
+ maxLabel.setVisible(true);
+
+ midLabel = new Label();
+ this.addChild(midLabel);
+ midLabel.setVisible(true);
+
+
+ }
+
+ public function setMax(max:Number):void {
+ this.max = max;
+ maxLabel.text = max.toExponential(1);
+ midLabel.text = (max / 2.0).toExponential(1);
+ }
+
+ private function myResize(event:Event):void {
+
+ this.height = parent.height * .90 * -1;
+ this.y = parent.height;
+ graphics.clear();
+ graphics.beginFill(0x000000);
+ graphics.lineStyle(1);
+
+ graphics.moveTo(width - 1,-1);
+ graphics.lineTo(width - 1,height);
+
+
+ graphics.moveTo(width - 4,height);
+ graphics.lineTo(width - 1,height);
+
+ graphics.moveTo(width - 4,height / 2);
+ graphics.lineTo(width - 1,height / 2);
+ graphics.endFill();
+
+ maxLabel.y = height;
+ midLabel.y = height / 2;
+
+ }
+ }
+}
diff --git a/src/flexchart/org/ovirt/elements/SingleBar.as b/src/flexchart/org/ovirt/elements/SingleBar.as
index e7caf93..40ae651 100644
--- a/src/flexchart/org/ovirt/elements/SingleBar.as
+++ b/src/flexchart/org/ovirt/elements/SingleBar.as
@@ -63,7 +63,6 @@ package org.ovirt.elements {
private function myResize(event:Event):void {
- trace(event.type);
this.height = (dataPoint.getValue() / scale) * parent.height * .9 * -1;
this.y = parent.height;
}
@@ -90,5 +89,13 @@ package org.ovirt.elements {
private function destroyTip(event:Event):void {
ToolTipManager.destroyToolTip(tip);
}
+
+ public function getResolution():Number {
+ return dataPoint.getResolution();
+ }
+
+ public function getStartTime():Number {
+ return dataPoint.getTimestamp().getTime();
+ }
}
}
--
1.6.0.6
More information about the ovirt-devel
mailing list