Skip to content

Instantly share code, notes, and snippets.

@gmcinnes
Created August 6, 2009 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gmcinnes/163402 to your computer and use it in GitHub Desktop.
Save gmcinnes/163402 to your computer and use it in GitHub Desktop.
package org.ehealthinnovation.chartDataProviders
{
import mx.charts.series.*;
public interface ChartDataProvider
{
function initialize(result:Object):AbstractChartDataProvider
function doLookup(callbackFunction:Object):void
function createGraphableVoCollection(result:Object):void
function numberOfDaysRepresented():int
function mainReadingSeries():Array
function rangeReadingSeries():Array
function minYValue():Number
function maxYValue():Number
function toArray():Array
function addAllReadingSeries():void
function addReadingSeries(xField:String, yField:String, id:String,
displayName:String, color:int, includeMarkers:Boolean=true,
interpolateValues:Boolean = true):LineSeries
}
}
package org.ehealthinnovation.chartDataProviders
{
import mx.charts.*;
import mx.charts.events.*;
import mx.charts.renderers.*;
import mx.charts.series.*;
import mx.core.ClassFactory;
import mx.graphics.*;
import org.ehealthinnovation.collections.*;
import org.ehealthinnovation.services.ReadingLookupService;
public class AbstractChartDataProvider
{
protected var _readingLookupService:ReadingLookupService;
protected var _readingArray:Array;
protected var _readingVoCollection:GraphableVoCollection;
protected var _millisecondsPerDay:int = 86400000;
protected var _numberOfDaysInTotal:Number;
protected var _pixelsPerDayAtMaxZoom:Number;
protected var _mainReadingSeries:Array = new Array();
protected var _rangeReadingSeries:Array = new Array();
protected var _patientId:String;
protected var _resourceName:String;
public var xAxisHoverName:String;
public var yAxisHoverName:String;
public function AbstractChartDataProvider(patientId:String, callbackFunction:Object) {
_patientId = patientId;
doLookup(callbackFunction);
}
protected function doLookup(callbackFunction:Object):void {
_readingLookupService = new ReadingLookupService(_patientId, _resourceName);
_readingLookupService.loadByHtml(function(result:Object):void {
var provider:AbstractChartDataProvider = initialize(result);
callbackFunction(provider);
});
}
protected function initialize(result:Object):AbstractChartDataProvider {
createGraphableVoCollection(result);
addAllReadingSeries();
return this;
}
protected function createGraphableVoCollection(result:Object):void {
throw new Error("Override me");
}
public function numberOfDaysRepresented():int {
if (_readingArray.length > 0) {
var firstReading:Object = _readingArray[0];
var lastReading:Object = _readingArray[_readingArray.length - 1];
return (lastReading.measuredAt - firstReading.measuredAt)/_millisecondsPerDay;
} else {
return 0
}
}
public function mainReadingSeries():Array {
return _mainReadingSeries;
}
public function rangeReadingSeries():Array {
return _rangeReadingSeries;
}
public function minYValue():Number {
return _readingVoCollection.minYValue();
}
public function maxYValue():Number {
return _readingVoCollection.maxYValue();
}
public function toArray():Array {
return _readingArray;
}
protected function addAllReadingSeries():void {
throw new Error("Override me");
}
protected function addReadingSeries(xField:String, yField:String, id:String,
displayName:String, color:int,
includeMarkers:Boolean=true,
interpolateValues:Boolean = true):LineSeries {
var series:LineSeries = new LineSeries;
series.xField = xField;
series.yField = yField;
series.id = id;
series.name = id;
series.displayName = displayName;
series.interpolateValues = interpolateValues;
series.setStyle('lineStroke', new Stroke(color, 2.5, 0.6, true));
if (includeMarkers == true) {
var circleItemRenderer:ClassFactory = new ClassFactory(mx.charts.renderers.CircleItemRenderer);
series.setStyle('itemRenderer', circleItemRenderer);
}
series.setStyle('fill', new SolidColor(0xFFFFFF, 0.6));
var stroke:Stroke = new Stroke(color, 1.5, 0.6, true);
series.setStyle('stroke', stroke);
series.setStyle('labelPosition', 'inside');
return series
}
}
}
package org.ehealthinnovation.chartDataProviders
{
public class WeightChartDataProvider extends AbstractChartDataProvider implements ChartDataProvider
{
import org.ehealthinnovation.services.ReadingLookupService;
import org.ehealthinnovation.collections.*;
public function WeightChartDataProvider(patientId:String, callbackFunction:Object) {
_resourceName = "weight_reading";
super(patientId, callbackFunction);
super.xAxisHoverName = "Date";
super.yAxisHoverName = "kgs";
}
protected override function createGraphableVoCollection(result:Object):void {
_readingVoCollection = new WeightReadingGraphableVoCollection(result);
_readingArray = _readingVoCollection.toArray();
}
protected override function addAllReadingSeries():void {
_mainReadingSeries.push(addReadingSeries('measuredAt', 'measurement', 'measurements', 'Weight (kg)', 0x0066DD));
_rangeReadingSeries.push(addReadingSeries('measuredAt', 'measurement', 'measurements', 'Weight (kg)', 0x0066DD, false));
}
}
}
//Brief idea:
//interface is ChartDataProvider
//Abstract base class is AbstractChartProvider
//Concrete class is WeightChartDataProvider
//WeightChartDataProvider extends AbstractChartProvider implements ChartDataProvider
//AbstractChartDataProvider's methods do some setup, and then drive the process with template methods, and //WeightChartDataProvider overrides some of AbstractChartDataProviders methods to specialize things (i.e. set //the right names for the line series etc.)
//Problem:
//Flex complains that WeightChartDataProvider does not implement the methods in the interface that it
//overrides from AbstractChartDataProvider. Taking the methods out of the AbstractChartDataProvider is not
//an option because then the template method can't drive things. Any thoughts about how to structure this?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment