Show:

File: ia\charts\layers\ComparisonLineLayer.js

/** 
 * The base class for comparison line layers.
 *
 * @author J Clare
 * @class ia.ComparisonLineLayer
 * @extends ia.ItemLayer
 * @constructor
 */
ia.ComparisonLineLayer = function()
{
	ia.ComparisonLineLayer.baseConstructor.call(this);

	this.style = {fillStyle:'#ffffff', strokeStyle:'#ff0000', lineWidth:'2', lineJoin:'round'};
	this.displayAll = false;
};
ia.extend(ia.ItemLayer, ia.ComparisonLineLayer);

/** 
 * The layer style.
 *
 * @property style
 * @type Object
 * @default {fillStyle:'#ffffff', strokeStyle:'#ff0000', lineWidth:'2', lineJoin:'round'}
 */
ia.ComparisonLineLayer.prototype.style;

/** 
 * The min bar value.
 *
 * @property minValue
 * @type Number
 */
ia.ComparisonLineLayer.prototype.minValue;

/** 
 * The max bar value.
 *
 * @property maxValue
 * @type Number
 */
ia.ComparisonLineLayer.prototype.maxValue;

/** 
 * Should all data be displayed.
 *
 * @property displayAll
 * @type Boolean
 * @default false
 */
ia.ComparisonLineLayer.prototype.displayAll;

/**
 * Updates the data.
 *
 * @method update
 */
ia.ComparisonLineLayer.prototype.update = function() 
{
	// Check if the data has changed
	if (this.map && this.dataChanged)
	{
		// Get the data.
		var data = this.getData()

		// Clear the items.
		this.itemArray = [];
		this.clearItems();
		
		this.minValue = Infinity;
		this.maxValue = -Infinity;
		
		// Loop through the data.
		for (var id in data)
		{
			// Get the data item.
			var dataItem = data[id];

			// Has to be a number to be displayed in a bar chart
			var value = dataItem[this.dataField];
			if (ia.isNumber(value)) 
			{	
			
				// Create a new chart item.
				var chartItem =  {};
				chartItem.id = dataItem.id;
				chartItem.name = dataItem.name;
				chartItem.color = dataItem.color;
				chartItem.value = dataItem[this.dataField];
				chartItem.shape = new ia.Rectangle();
				chartItem.hitArea = new ia.Rectangle();

				chartItem.state = ia.ItemLayer.UNSELECTED;
				if (this.selectionIds.indexOf(chartItem.id) !== -1) 
				{
					// Get the min and max bar values for the layer.
					this.minValue = Math.min(this.minValue, value);
					this.maxValue = Math.max(this.maxValue, value);
					chartItem.state = ia.ItemLayer.SELECTED;
				}
				if (this.displayAll)
				{
					// Get the min and max bar values for the layer.
					this.minValue = Math.min(this.minValue, value);
					this.maxValue = Math.max(this.maxValue, value);
				}
				chartItem.parent = this;
				chartItem.layer = this;

				this.items[id] = chartItem;
				this.itemArray.push(chartItem);
			}
		}
		
		this.dataChanged = false;
	}
};

/**
 * Renders the data.
 *
 * @method render
 */
ia.ComparisonLineLayer.prototype.render = function() 
{
	// Clear the canvas.
	this.clear();
	
	// Reset the context styles in case the layer styles has changed.
	for (var p in this.style) 
	{
		this.context[p] = this.style[p];
		this.highlightContext[p] = this.style[p];
		this.selectionContext[p] = this.style[p];
	} 
	this.highlightContext.strokeStyle = ia.Color.toRGBA(this.highlightColor);
	
	// Set the items shape.
	var nItems = this.itemArray.length;
	for (var i = 0; i < nItems; i++) 
	{
		var chartItem = this.itemArray[i];
		this._setItemShape(chartItem);
		if (this.displayAll) this._renderItem(chartItem);
	}

	if (!this.displayAll) this.renderSelection();
};

/**
 * Sets an items dimensions.
 *
 * @method _setItemShape
 * @param {Object} item The item.
 * @private
 */
ia.ComparisonLineLayer.prototype._setItemShape = function(item)
{
	if (this.map.orientation === "vertical")
	{
		// Reset the pixel drawing area for the point.
		item.shape.x = this.map.canvasX;
		item.shape.y = this.map.getPixelY(item.value);
		item.shape.width = this.map.canvasWidth;
		item.shape.height = 0;

		// Reset the pixel hit area for the point.
		item.hitArea.x = item.shape.x;
		item.hitArea.y = item.shape.y - 1;
		item.hitArea.width = item.shape.width;
		item.hitArea.height = 2;
	}
	else
	{
		// Reset the pixel drawing area for the point.
		item.shape.x = this.map.getPixelX(item.value);
		item.shape.y = this.map.canvasY;
		item.shape.width = 0;
		item.shape.height = this.map.canvasHeight;

		// Reset the pixel hit area for the point.
		item.hitArea.x = item.shape.x - 1;
		item.hitArea.y = item.shape.y;
		item.hitArea.width = 2;
		item.hitArea.height = item.shape.height;
	}
};

/**
 * Clears all selections.
 *
 * @method clearSelection
 */
ia.ComparisonLineLayer.prototype.clearSelection = function() {};

/**
 * Renders the item to the given context.
 *
 * @method _renderItem
 * @param {Object} item The item.
 * @private
 */
ia.ComparisonLineLayer.prototype._renderItem = function(item)
{
	this.context.strokeStyle = item.color;
	this._drawItem(item, this.context);
};

/**
 * Selects the item.
 *
 * @method selectItem
 * @param {Object} item The item.
 */
ia.ComparisonLineLayer.prototype.selectItem = function(item)
{	
	this.selectionContext.strokeStyle = item.color;
	this._drawItem(item, this.selectionContext);
};

/**
 * Highlights the item.
 *
 * @method highlightItem
 * @param {Object} item The item.
 */
ia.ComparisonLineLayer.prototype.highlightItem = function(item)
{	
	// Clip.
	if (!ia.IS_IE_TEN)
	{
		this.highlightContext.beginPath();
	    this.highlightContext.rect(this.map.canvasX, this.map.canvasY, this.map.canvasWidth, this.map.canvasHeight);
	    this.highlightContext.clip();
	}
	
	this._drawItem(item, this.highlightContext);
};

/**
 * Does the actual drawing.
 *
 * @method _drawItem
 * @param {Object} item The item.
 * @param {HTML Canvas Context} ctx The context to render to.
 * @private
 */
ia.ComparisonLineLayer.prototype._drawItem = function(item, ctx)
{
	ctx.beginPath();
		if (this.map.orientation === "vertical")
		{
			ctx.moveTo(item.shape.x, item.shape.y);
			ctx.lineTo(item.shape.x+item.shape.width, item.shape.y);
		}
		else
		{
			ctx.moveTo(item.shape.x, item.shape.y);
			ctx.lineTo(item.shape.x, item.shape.y+item.shape.height);
		
		}
	ctx.stroke();
};

/**
 * Runs a hit test on an item. 
 * 
 * @method hitItem
 * @param {Object} item The item to hit test.
 * @param {ia.MapMouseEvent} event An <code>ia.MapMouseEvent</code>.
 */
ia.ComparisonLineLayer.prototype.hitItem = function(item, event)
{
	if (this.isSelected(item.id) || this.displayAll)
	{
		return item.hitArea.intersects(event.x, event.y);	
	}
	return false;
};

/** 
 * Displays the tip for the passed item
 * 
 * @method showTip
 * @param {Object} item The map item.	 
 * @param {ia.ItemEvent} event An <code>ia.ItemEvent</code>.
 */
ia.ComparisonLineLayer.prototype.showTip = function(item, event)
{
	this.map.datatip.text(this.tipFunction(item));
	
	// Position above the bar.
	var px,py;

	if (ia.IS_TOUCH_DEVICE)
	{
		px = event.x - (this.map.datatip.getWidth() / 2);
		py = event.y - (this.map.datatip.getHeight() + 30);
	}
	else
	{
		if (this.map.orientation === "vertical")
		{
			px = event.x -  (this.map.datatip.getWidth() / 2);
			py = item.shape.y - this.map.datatip.getHeight() - 5;
		}
		else
		{
			px = (item.shape.x + item.shape.width) + 5;
			py = event.y -  (this.map.datatip.getHeight() / 2);
		}
	}
	this.map.datatip.position(px, py);
	this.map.datatip.show();
};