[Ovirt-devel] [PATCH server] Add time range and data type selection to flexchart.
Steve Linabery
slinabery at redhat.com
Thu Nov 20 04:12:04 UTC 2008
Also
-change color scheme to match tallen prototype pallette
-change SingleBar elements to dynamically resized Canvas objects instead of HBox objects
-add new route to accept second-resolution timestamps for time range selection
---
src/app/controllers/graph_controller.rb | 59 ++++-
src/app/util/stats/StatsTypes.rb | 8 +-
src/app/views/graph/history_graphs.rhtml | 2 +-
src/config/routes.rb | 1 +
src/flexchart/flexchart.mxml | 12 +-
src/flexchart/org/ovirt/ApplicationBus.as | 39 ++++
src/flexchart/org/ovirt/Constants.as | 2 +-
src/flexchart/org/ovirt/DataSource.as | 7 +-
src/flexchart/org/ovirt/charts/BarChart.as | 287 ++++++++++++++++++------
src/flexchart/org/ovirt/charts/Chart.as | 38 +++-
src/flexchart/org/ovirt/data/DataPoint.as | 7 +-
src/flexchart/org/ovirt/data/DataSeries.as | 12 +-
src/flexchart/org/ovirt/elements/SingleBar.as | 51 ++++-
src/flexchart/org/ovirt/elements/XAxisLabel.as | 66 ++++++
src/flexchart/org/ovirt/elements/YAxisLabel.as | 17 +--
15 files changed, 476 insertions(+), 132 deletions(-)
create mode 100644 src/flexchart/org/ovirt/ApplicationBus.as
create mode 100644 src/flexchart/org/ovirt/elements/XAxisLabel.as
diff --git a/src/app/controllers/graph_controller.rb b/src/app/controllers/graph_controller.rb
index 0105ea6..d636544 100644
--- a/src/app/controllers/graph_controller.rb
+++ b/src/app/controllers/graph_controller.rb
@@ -4,20 +4,53 @@ class GraphController < ApplicationController
layout nil
def flexchart_data
-
- #FIXME: use the stats package aggregation (when it's available)
- #instead of the old method
- graph_obj = history_graph_data_object
-
- #FIXME: for this release, the flexchart shows only peak values,
- # and only shows a default of the last 40 data points in rrd.
- graph_data = { :labels => graph_obj[:timepoints].last(40),
- :values => graph_obj[:dataset][2][:values].last(40) }
- my_data = graph_data[:labels].zip(graph_data[:values])
- graph = { :vectors => my_data,
- :max_value => graph_obj[:total_peak],
- :description => params[:target]
- }
+ @id = params[:id]
+ target = params[:target]
+ startTime = params[:startTime].to_i
+ endTime = params[:endTime].to_i
+ duration = endTime - startTime
+
+ #the maximum number of data points we want in any chart
+ maxPoints = 100
+ resolution =
+ case
+ when duration / RRDResolution::Minimum < maxPoints
+ RRDResolution::Minimum
+ when duration / RRDResolution::Short < maxPoints
+ RRDResolution::Short
+ when duration / RRDResolution::Medium < maxPoints
+ RRDResolution::Medium
+ when duration / RRDResolution::Long < maxPoints
+ RRDResolution::Long
+ else
+ RRDResolution::Maximum
+ end
+ devclass = DEV_KEY_CLASSES[target]
+ counter = DEV_KEY_COUNTERS[target]
+
+ #FIXME: until stats aggregation is pushed, we just get stats data for
+ # the first host in the pool. If no host in pool, the chart will be
+ # empty.
+ pool = Pool.find(@id)
+ hosts = pool.hosts
+ host = pool.hosts[0]
+ requestList = [ ]
+ requestList.push StatsRequest.new(host.hostname, devclass, 0, counter, startTime, duration, resolution, DataFunction::Peak)
+ statsList = getStatsData?(requestList)
+
+ #The aggregated (summed) stats will come back as a single stats list
+ stat = statsList[0]
+ vectors = [ ]
+ data = stat.get_data?
+ data.each{ |datum|
+ val = datum.get_value?
+ val = 0 if val.nan?
+ vectors.push [datum.get_timestamp?.to_i, val]
+ }
+ graph = { :vectors => vectors,
+ :max_value => stat.get_max_value?,
+ :description => target
+ }
render :json => graph
end
diff --git a/src/app/util/stats/StatsTypes.rb b/src/app/util/stats/StatsTypes.rb
index 41c2977..4896bb3 100644
--- a/src/app/util/stats/StatsTypes.rb
+++ b/src/app/util/stats/StatsTypes.rb
@@ -324,10 +324,12 @@ class RRDResolution
end
# Set up the resolutions for our rrd
+ RRDResolution.add_item :Minimum, 10 # Ten secs
+ RRDResolution.add_item :Short, 70 # Seventy secs
+ RRDResolution.add_item :Medium, 500 # 500 secs ( 8minute, 20 sec)
+ RRDResolution.add_item :Long, 2230
+ RRDResolution.add_item :Maximum, 26350
RRDResolution.add_item :Default, 10 # Ten secs
- RRDResolution.add_item :Short, 500 # 500 secs ( 8minute, 20 sec)
- RRDResolution.add_item :Medium, 2230
- RRDResolution.add_item :Long, 26350
end
diff --git a/src/app/views/graph/history_graphs.rhtml b/src/app/views/graph/history_graphs.rhtml
index bebe5d9..97ed67f 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/1" }
+ flashvars: { flexchart_data: "<%= url_for :controller =>'/graph', :action => 'flexchart_data' %>/<%= @id %>/memory/<%= Time.now.to_i - 60 * 60 * 24 %>/<%= Time.now.to_i %>" }
},
{ version: 9 }
);
diff --git a/src/config/routes.rb b/src/config/routes.rb
index 8d538cb..0dbe0d6 100644
--- a/src/config/routes.rb
+++ b/src/config/routes.rb
@@ -41,6 +41,7 @@ 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 ':controller/:action/:id.:format'
map.connect ':controller/:action/:id'
diff --git a/src/flexchart/flexchart.mxml b/src/flexchart/flexchart.mxml
index 35fa9a6..c4a089f 100644
--- a/src/flexchart/flexchart.mxml
+++ b/src/flexchart/flexchart.mxml
@@ -6,6 +6,7 @@
import mx.containers.VBox;
import mx.effects.Resize;
import org.ovirt.Constants;
+ import org.ovirt.ApplicationBus;
import org.ovirt.charts.Chart;
import org.ovirt.charts.BarChart;
@@ -21,6 +22,7 @@
private var contractResources:Resize = new Resize();
private function myInit():void {
+
mainChart.height = Constants.height;
mainChart.width = Constants.width;
hostsChart.width = Constants.width;
@@ -42,6 +44,9 @@
contractResources.heightTo = 0;
contractResources.target = hostsChart;
contractResources.duration = 500;
+
+ ApplicationBus.instance().barClickAction = zoomIntoSeries;
+
}
private function zoomOutSeries(e:Event):void {
@@ -61,7 +66,8 @@
</mx:Script>
- <mx:VBox id="mainChart" click="zoomIntoSeries(event)" />
- <mx:VBox id="hostsChart" visible="false" opaqueBackground="0x00ff00" click="zoomOutSeries(event)"/>
-
+ <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:VBox>
</mx:Application>
diff --git a/src/flexchart/org/ovirt/ApplicationBus.as b/src/flexchart/org/ovirt/ApplicationBus.as
new file mode 100644
index 0000000..7d6d431
--- /dev/null
+++ b/src/flexchart/org/ovirt/ApplicationBus.as
@@ -0,0 +1,39 @@
+/*
+ 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.
+*/
+
+//A way to expose some functions that are defined in flexchart.mxml to
+//our ActionScript classes without needing to access Application directly
+
+package org.ovirt {
+ public class ApplicationBus {
+
+ private static var _instance:ApplicationBus;
+
+ public static function instance():ApplicationBus {
+ if (_instance == null) {
+ _instance = new ApplicationBus();
+ }
+ return _instance;
+ }
+
+ public var barClickAction:Function;
+
+ }
+}
diff --git a/src/flexchart/org/ovirt/Constants.as b/src/flexchart/org/ovirt/Constants.as
index 996a31e..14f6465 100644
--- a/src/flexchart/org/ovirt/Constants.as
+++ b/src/flexchart/org/ovirt/Constants.as
@@ -23,6 +23,6 @@ package org.ovirt {
public static var width:int = 722;
public static var height:int = 297;
public static var barSpacing:int = 2;
- public static var labelHeight:int = 40;
+ public static var labelHeight:int = 20;
}
}
diff --git a/src/flexchart/org/ovirt/DataSource.as b/src/flexchart/org/ovirt/DataSource.as
index 44e482d..4438900 100644
--- a/src/flexchart/org/ovirt/DataSource.as
+++ b/src/flexchart/org/ovirt/DataSource.as
@@ -20,13 +20,13 @@
package org.ovirt {
- import flash.net.URLLoader;
- import flash.net.URLRequest;
import com.adobe.serialization.json.JSON;
import flash.events.Event;
import flash.events.IOErrorEvent;
- import org.ovirt.data.DataSeries;
+ import flash.net.URLLoader;
+ import flash.net.URLRequest;
import org.ovirt.charts.Chart;
+ import org.ovirt.data.DataSeries;
public class DataSource {
@@ -52,6 +52,7 @@ package org.ovirt {
}
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 83cf0bb..88a75ca 100644
--- a/src/flexchart/org/ovirt/charts/BarChart.as
+++ b/src/flexchart/org/ovirt/charts/BarChart.as
@@ -19,40 +19,127 @@
*/
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.controls.Text;
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;
public class BarChart extends Chart {
- private var chartArea:HBox;
- private var labelArea:Canvas;
+ private var chartArea:Canvas;
+ private var XAxisLabelArea:Canvas;
+ private var startDateField:DateField;
+ private var endDateField:DateField;
+ private var startTimeField:TextInput;
+ private var endTimeField:TextInput;
+ private var button:Button;
+ private var menu:PopUpMenuButton;
+ private var dateBar:Box;
+ private var datePattern:RegExp;
+
public function BarChart(container:Box,
datasourceUrl:String) {
super(container,datasourceUrl);
- chartArea = new HBox();
- chartArea.setStyle("horizontalGap",Constants.barSpacing);
- chartArea.setStyle("verticalAlign","bottom");
+ container.setStyle("verticalGap","2");
+ datePattern = /^(\d+):(\d+)$/;
+ }
+
+
+ private function timeRangeAdjusted(event:Event):void {
+ var t1:Number = startDateField.selectedDate.getTime()
+ + (parseHour(startTimeField.text) * 3600 * 1000)
+ + (parseMinute(startTimeField.text) * 60 * 1000);
+ setStartTime(Math.floor(t1 / 1000));
+ var t2:Number = endDateField.selectedDate.getTime()
+ + (parseHour(endTimeField.text) * 3600 * 1000)
+ + (parseMinute(endTimeField.text) * 60 * 1000);
+ setEndTime(Math.floor(t2 / 1000));
+ load();
+ }
+
+ private function typeSelected(event:MenuEvent):void {
+ target = event.label;
+ load();
+ }
+
+
+ private function pad(input:int):String {
+ if (input < 10) {
+ return "0" + input;
+ } else {
+ return "" + input;
+ }
+ }
+
+ private function parseHour(input:String):int {
+ var answer:int = 0;
+ try {
+ var obj:Object = datePattern.exec(input);
+ if (obj != null) {
+ answer = int(obj[1].toString());
+ }
+ } catch (e:Error) {}
+ return answer;
+ }
+
+ private function parseMinute(input:String):int {
+ var answer:int = 0;
+ try {
+ var obj:Object = datePattern.exec(input);
+ if (obj != null) {
+ answer = int(obj[2].toString());
+ }
+ } catch (e:Error) {}
+ return answer;
+ }
+
+ override public function addData(dataSeries:DataSeries):void {
+ container.removeAllChildren();
+
+ var dateFormat:DateFormatter = new DateFormatter();
+
+ //since we're reusing objects, we need to get rid of stale
+ //EventListener references
+ if (chartArea != null) {
+ var kids:Array = chartArea.getChildren();
+ var i:int;
+ for (i = 0; i < kids.length; i++) {
+ (kids[i] as SingleBar).destroy();
+ }
+ }
+
+ chartArea = new Canvas();
chartArea.percentHeight = 80;
chartArea.percentWidth = 100;
+ chartArea.setStyle("backgroundColor","0xbbccdd");
this.container.addChild(chartArea);
- labelArea = new Canvas();
- labelArea.height = Constants.labelHeight;
- labelArea.minHeight = Constants.labelHeight;
- labelArea.percentWidth = 100;
- this.container.addChild(labelArea);
- }
+ XAxisLabelArea = new Canvas();
+ XAxisLabelArea.height = Constants.labelHeight;
+ XAxisLabelArea.minHeight = Constants.labelHeight;
+ XAxisLabelArea.percentWidth = 100;
+ this.container.addChild(XAxisLabelArea);
- override public function addData(dataSeries:DataSeries):void {
try {
+
+ dateBar = new HBox();
+ dateBar.setVisible(true);
+ this.container.addChild(dateBar);
var dataPoints:Array = dataSeries.getDataPoints();
var maxValue:Number = dataSeries.getMaxValue();
var scale:Number = maxValue;
@@ -65,74 +152,72 @@ package org.ovirt.charts {
throw new Error("No data points in range");
}
- //have to iterate through datapoint.timestamp strings,
- //create a TextLiberation object with them, and add them to
- //a parent container before we can tell how wide they are in pixels.
- var labelWidth:Number = 0;
- for (var i:int = 0; i < size; i++) {
- var dataPoint:DataPoint = dataPoints[i] as DataPoint;
- var textTemp:TextLiberation =
- new TextLiberation(dataPoint.getTimestamp());
- textTemp.setVisible(false);
- chartArea.addChild(textTemp);
- var tempLabelWidth:Number = textTemp.getTextWidth();
- if (! isNaN(tempLabelWidth)) {
- labelWidth = Math.max(labelWidth, tempLabelWidth);
- }
- }
- //now we have to remove all the children we just added, since we don't
- //really want them to be part of the chart.
- chartArea.removeAllChildren();
-
- //we always want an odd number of y-axis labels, and we'll
- //determine this by using the labelWidth we just determined
- var labelCount:int = Math.floor(Constants.width / labelWidth);
- if (labelCount > 3 && labelCount % 2 == 1) {
- labelCount--;
- }
-
//the distance between left edges of adjacent bars
- var gridWidth:Number = Constants.width / size;
+ var gridWidth:Number = Math.floor(Constants.width / size);
//the width of each SingleBar (does not including padding between bars)
var barWidth:Number = gridWidth - Constants.barSpacing;
- //use this to center y-axis labels on the bars
- var labelOffset:Number = barWidth / 2;
+ //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 makeup:Number = Math.round(size / shortfall);
+ var madeup:Number = 0;
+
+ //variable to hold the numbered day of the month of the last
+ //XAxisLabel added to the label area
+ var lastDate:Number;
- //distance between first and last label
- var labelSpace:Number = Constants.width - gridWidth;
- var labelSpacing:Number = labelSpace / labelCount;
+ //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++) {
- dataPoint = dataPoints[i] as DataPoint;
+
+ var dataPoint:DataPoint = dataPoints[i] as DataPoint;
+ if (i == 0) {
+ lastDate = dataPoint.getTimestamp().date;
+ }
+
+ //show long date format for first & last XAxisLabels,
+ //as well as whenever the date changes
+ if (i == 0 || i == size - 1
+ || dataPoint.getTimestamp().date != lastDate) {
+ dateFormat.formatString = "DD-MMM-YYYY JJ:NN";
+ } else {
+ dateFormat.formatString = "JJ:NN";
+ }
+
var value:Number = dataPoint.getValue();
- var bar:SingleBar = new SingleBar(dataPoint);
- bar.percentHeight = ((value / scale) * 80);
- bar.width = barWidth;
- bar.setVisible(true);
+ var bar:SingleBar = new SingleBar(dataPoint,scale);
chartArea.addChild(bar);
- var currentLabelPosition:int = labelCounter * labelSpacing +
- labelOffset;
-
- if (currentLabelPosition >= i * gridWidth &&
- currentLabelPosition < (i + 1) * gridWidth) {
- var label:YAxisLabel = new YAxisLabel(dataPoint.getTimestamp());
- label.setVisible(false);
- label.y = ((labelCounter + 1) % 2) * 13 + 4;
- labelArea.addChild(label);
- //make sure the label is fully within the chart width
- label.x = Math.max(0,
- Math.min((i) * gridWidth -
- (label.labelText.getTextWidth() / 2) +
- labelOffset,
- Constants.width -
- label.labelText.getTextWidth() - 6)
- );
+ bar.width = barWidth;
+ bar.addEventListener(MouseEvent.CLICK,
+ ApplicationBus.instance().barClickAction);
+ bar.x = currentBarPosition;
+ if (makeup > 0 && i % makeup == 0 && madeup < shortfall) {
+ bar.width = bar.width + 1;
+ madeup++;
+ }
+
+ //add XAxisLabels at the endpoints of the time range,
+ //as well as the center if there are more than 6 points
+ //and two more if there are more than 14 points
+ if ((size > 6 && i == Math.floor(size / 2))
+ || (size > 14
+ && (i == Math.floor(size / 4)
+ || i == Math.floor(size * 3 / 4)))
+ || i == 0
+ || i == size - 1) {
+ var label:XAxisLabel =
+ new XAxisLabel(dateFormat.format(dataPoint.getTimestamp()));
+ label.setCenter(currentBarPosition + bar.width / 2);
label.setVisible(true);
- labelCounter++;
+ label.y = 6;
+ XAxisLabelArea.addChild(label);
//add a 'tick' in the center of the bar to which this label
//corresponds
@@ -140,13 +225,73 @@ package org.ovirt.charts {
ind.opaqueBackground = 0x000000;
ind.width=1;
ind.height=3;
- ind.x = (i) * gridWidth + labelOffset;
+ ind.x = label.getCenter();
ind.y = 0;
ind.setVisible(true);
ind.setStyle("backgroundColor","0x000000");
- labelArea.addChild(ind);
+ XAxisLabelArea.addChild(ind);
+ lastDate = dataPoint.getTimestamp().date;
}
+ 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);
+
} catch (e:Error) {
var err:Text = new Text();
err.text = e.message;
diff --git a/src/flexchart/org/ovirt/charts/Chart.as b/src/flexchart/org/ovirt/charts/Chart.as
index 26c8d02..f2faf33 100644
--- a/src/flexchart/org/ovirt/charts/Chart.as
+++ b/src/flexchart/org/ovirt/charts/Chart.as
@@ -19,19 +19,32 @@
*/
package org.ovirt.charts {
-
- public class Chart {
-
import org.ovirt.DataSource;
import mx.containers.Box;
import org.ovirt.data.DataSeries;
+ public class Chart {
+
protected var container:Box;
protected var datasourceUrl:String;
+ protected var startTime:Number;
+ protected var endTime:Number;
+ protected var target:String;
+ protected var id:int;
+
public function Chart(container:Box, datasourceUrl:String) {
this.container = container;
this.datasourceUrl = datasourceUrl;
+ if (datasourceUrl != null) {
+ var results:Array = datasourceUrl.split("/");
+ if (results != null && results.length > 7) {
+ setId(new int(results[4]));
+ setTarget(results[5] as String);
+ setStartTime(new int(results[6]));
+ setEndTime(new int(results[7]));
+ }
+ }
}
public function addData(dataSeries:DataSeries):void {
@@ -40,7 +53,24 @@ package org.ovirt.charts {
public function load():void {
var dataSource:DataSource = new DataSource(this);
- dataSource.retrieveData(datasourceUrl);
+ var myString:String = "/ovirt/graph/flexchart_data/" + id + "/" + target + "/" + startTime + "/" + endTime;
+ dataSource.retrieveData(myString);
+ }
+
+ 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;
}
}
}
diff --git a/src/flexchart/org/ovirt/data/DataPoint.as b/src/flexchart/org/ovirt/data/DataPoint.as
index 00cd0a4..5d59de9 100644
--- a/src/flexchart/org/ovirt/data/DataPoint.as
+++ b/src/flexchart/org/ovirt/data/DataPoint.as
@@ -22,17 +22,18 @@ package org.ovirt.data {
public class DataPoint {
- private var timestamp:String;
+ private var timestamp:Date;
private var value:Number;
private var description:String;
- public function DataPoint (timestamp:String, value:Number, description:String) {
+ public function DataPoint (timestamp:Date, value:Number,
+ description:String) {
this.timestamp = timestamp;
this.value = value;
this.description = description;
}
- public function getTimestamp():String {
+ public function getTimestamp():Date {
return timestamp;
}
diff --git a/src/flexchart/org/ovirt/data/DataSeries.as b/src/flexchart/org/ovirt/data/DataSeries.as
index 764fd34..eb653e9 100644
--- a/src/flexchart/org/ovirt/data/DataSeries.as
+++ b/src/flexchart/org/ovirt/data/DataSeries.as
@@ -36,9 +36,15 @@ package org.ovirt.data {
dataPoints = new Array();
var inDataPoints:Array = object["vectors"] as Array;
for (var i:int = 0; i < inDataPoints.length; i++) {
- dataPoints.push(new DataPoint((inDataPoints[i] as Array)[0] as String,
- (inDataPoints[i] as Array)[1] as Number,
- description));
+ var value:Number = 0;
+ var valuea:Number = (inDataPoints[i] as Array)[1] as Number;
+ if (!isNaN(valuea)) {
+ value = (inDataPoints[i] as Array)[1] as Number;
+ }
+ var seconds:int = int((inDataPoints[i] as Array)[0]) * 1000;
+ dataPoints.push(new DataPoint(new Date(seconds),
+ value,
+ description));
}
maxValue = object["max_value"] as Number;
}
diff --git a/src/flexchart/org/ovirt/elements/SingleBar.as b/src/flexchart/org/ovirt/elements/SingleBar.as
index 6e09bff..e7caf93 100644
--- a/src/flexchart/org/ovirt/elements/SingleBar.as
+++ b/src/flexchart/org/ovirt/elements/SingleBar.as
@@ -20,39 +20,66 @@
package org.ovirt.elements {
- import mx.containers.Box;
- import mx.controls.ToolTip;
- import mx.managers.ToolTipManager;
+ import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
- import flash.display.DisplayObject;
+ import mx.containers.Canvas;
+ import mx.controls.ToolTip;
+ import mx.events.FlexEvent;
+ import mx.events.ResizeEvent;
+ import mx.formatters.DateFormatter;
+ import mx.managers.ToolTipManager;
import org.ovirt.data.DataPoint;
- public class SingleBar extends Box {
+ public class SingleBar extends Canvas {
private var tip:ToolTip;
private var dataPoint:DataPoint;
+ private var scale:Number;
+ private var dateFormat:DateFormatter = new DateFormatter();
- public function SingleBar(dataPoint:DataPoint) {
+ public function SingleBar(dataPoint:DataPoint,scale:Number) {
super();
this.dataPoint = dataPoint;
+ this.scale = scale;
addEventListener(MouseEvent.MOUSE_OVER,showTip);
addEventListener(MouseEvent.MOUSE_OUT,destroyTip);
- this.setStyle("backgroundColor","0x0000FF");
- this.setStyle("left","1");
- this.setStyle("right","1");
+ addEventListener(ResizeEvent.RESIZE,myResize);
+ addEventListener(FlexEvent.CREATION_COMPLETE,myResize);
+ addEventListener(Event.RENDER,myResize);
+ this.setStyle("backgroundColor","0x2875c1");
+ dateFormat.formatString = "DD-MMM-YYYY JJ:NN";
+ }
+
+ public function destroy():void {
+ removeEventListener(MouseEvent.MOUSE_OVER,showTip);
+ removeEventListener(MouseEvent.MOUSE_OUT,destroyTip);
+ removeEventListener(ResizeEvent.RESIZE,myResize);
+ removeEventListener(FlexEvent.CREATION_COMPLETE,myResize);
+ removeEventListener(FlexEvent.UPDATE_COMPLETE,myResize);
+ removeEventListener(Event.RENDER,myResize);
+ }
+
+
+ private function myResize(event:Event):void {
+ trace(event.type);
+ this.height = (dataPoint.getValue() / scale) * parent.height * .9 * -1;
+ this.y = parent.height;
}
private function showTip(event:Event):void {
+
var w:Number = this.stage.width;
var target:DisplayObject = event.currentTarget as DisplayObject;
var pt:Rectangle = this.stage.getBounds(target);
var yPos:Number = pt.y * -1;
var xPos:Number = pt.x * -1;
- tip = ToolTipManager.createToolTip(dataPoint.getDescription() + "\n" +
- dataPoint.getTimestamp() + "\n" +
- dataPoint.getValue(),
+ tip = ToolTipManager.createToolTip(dataPoint.getDescription() +
+ "\n" +
+ dateFormat.format(dataPoint.getTimestamp()) +
+ "\n" +
+ dataPoint.getValue(),
xPos,yPos) as ToolTip;
tip.x = Math.min(tip.x,
w - tip.width);
diff --git a/src/flexchart/org/ovirt/elements/XAxisLabel.as b/src/flexchart/org/ovirt/elements/XAxisLabel.as
new file mode 100644
index 0000000..9bf4c26
--- /dev/null
+++ b/src/flexchart/org/ovirt/elements/XAxisLabel.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.elements {
+
+ import mx.containers.Box;
+ import mx.core.ScrollPolicy;
+ import flash.events.*;
+ import flash.events.MouseEvent;
+ import mx.events.*;
+ import mx.events.FlexEvent;
+
+ public class XAxisLabel extends Box {
+
+ public var labelText:TextLiberation;
+ private var center:int;
+
+ public function XAxisLabel(text:String) {
+ super();
+ labelText = new TextLiberation(text);
+ labelText.setVisible(true);
+ this.addChild(labelText);
+ this.horizontalScrollPolicy = ScrollPolicy.OFF;
+ this.verticalScrollPolicy = ScrollPolicy.OFF;
+ this.setStyle("paddingLeft","0");
+ this.setStyle("paddingRight","0");
+ addEventListener(FlexEvent.CREATION_COMPLETE,centerLabel);
+ }
+
+ public function setCenter(center:int):void {
+ this.center = center;
+ }
+
+ public function getCenter():int {
+ return center;
+ }
+
+ private function centerLabel(event:Event):void {
+ this.x = center - labelText.getTextWidth() / 2;
+ if (parent != null) {
+ if (this.x < 0) {
+ this.x = 0;
+ } else if (this.x > parent.width - labelText.getTextWidth() - 5) {
+ this.x = parent.width - labelText.getTextWidth() - 5;
+ }
+ }
+ }
+ }
+}
diff --git a/src/flexchart/org/ovirt/elements/YAxisLabel.as b/src/flexchart/org/ovirt/elements/YAxisLabel.as
index 0e93b97..73e1239 100644
--- a/src/flexchart/org/ovirt/elements/YAxisLabel.as
+++ b/src/flexchart/org/ovirt/elements/YAxisLabel.as
@@ -18,24 +18,11 @@
also available at http://www.gnu.org/copyleft/gpl.html.
*/
-package org.ovirt.elements {
+//class for labeling the scale of the y-axis of a chart
- import mx.containers.Box;
- import mx.core.ScrollPolicy;
+package org.ovirt.elements {
public class YAxisLabel extends Box {
- public var labelText:TextLiberation;
-
- public function YAxisLabel(text:String) {
- super();
- labelText = new TextLiberation(text);
- labelText.setVisible(true);
- this.addChild(labelText);
- this.horizontalScrollPolicy = ScrollPolicy.OFF;
- this.verticalScrollPolicy = ScrollPolicy.OFF;
- this.setStyle("paddingLeft","0");
- this.setStyle("paddingRight","0");
- }
}
}
--
1.5.6.5
More information about the ovirt-devel
mailing list