Show:

File: ia\ui\GradientLegend.js

/** 
 * A class for rendering a gradient legend.
 *
 * @author J Clare
 * @class ia.GradientLegend
 * @extends ia.EventDispatcher
 * @constructor
 * @param {String} id The id of the the legend.
 */
ia.GradientLegend = function(id)
{		
	ia.GradientLegend.baseConstructor.call(this);
	
	this.id = id;
	
	// The legend labels.
	this._minValue = undefined;
	this._maxValue = undefined;
	this._minLabel = undefined;
	this._maxLabel = undefined;

	// Canvases.
	this._canvas = undefined;
	this._context = undefined;

	// A div to contain the legend and allow correct scrolling
	this.container = $j("<div id='"+id+"' class='ia-legend'>");
	
	// A table used to render the legend.
	this.$table = $j("<table>");
	this.container.append(this.$table);
	this.style = {fillStyle:'#EFEFEF', strokeStyle:'#cccccc', lineWidth:'1', lineJoin:'miter'};
};
ia.extend(ia.EventDispatcher, ia.GradientLegend);

/** 
 * The id.
 * 
 * @property id
 * @type String
 */
ia.GradientLegend.prototype.id;

/**
 * The style.
 * 
 * @property style
 * @type Object
 * @default {fillStyle:'#EFEFEF', strokeStyle:'#cccccc', lineWidth:'0.5', lineJoin:'miter'}
 */
ia.GradientLegend.prototype.style;

/**
 * A thematic that can be associated with the data in the legend.
 * 
 * @property thematic
 * @type ia.Thematic
 */
ia.GradientLegend.prototype.thematic;

/** 
 * The item highlight color.
 *
 * @property highlightColor
 * @type String
 */
ia.GradientLegend.prototype.highlightColor;

/**
 * The container that holds the object.
 * 
 * @property container
 * @type JQUERY Element
 */
ia.GradientLegend.prototype.container;

/**
 * Renders the legend.
 *
 * @method render
 */
ia.GradientLegend.prototype.render = function() 
{		
	if (this.thematic.symbol === ia.Shape.SQUARE || this.thematic.symbol === ia.Shape.LINE) 
	{
		this._build(20, 120); 
		this._renderBlock(); 
	}
	else 
	{
		var maxSymbolSize =  Math.max(this.thematic.numericClassifier.sizePalette.minSize, 
		this.thematic.numericClassifier.sizePalette.maxSize);
		this._build(maxSymbolSize + 10, maxSymbolSize + 10);
		this._renderPoint();
	}
};

/**
 * Builds the legend.
 *
 * @method _build
 * @param {Number} cw The width.
 * @param {Number} ch The height.
 * @private
 */
ia.GradientLegend.prototype._build = function(cw, ch) 
{	
	this.$table.empty();

	// Get the breaks.
	var breaks = this.thematic.numericClassifier.getBreaks();
	this._minValue = breaks[0];
	this._maxValue = breaks[breaks.length-1];

	// Text.
	var minText;
	var maxText;
	if (this.thematic.numericClassifier.sizePalette.maxSize >= this.thematic.numericClassifier.sizePalette.minSize)
	{
		minText = this.thematic.numericClassifier.formatter.format(this._minValue);
		maxText = this.thematic.numericClassifier.formatter.format(this._maxValue);
	}
	else
	{
		minText = this.thematic.numericClassifier.formatter.format(this._maxValue);
		maxText = this.thematic.numericClassifier.formatter.format(this._minValue);
	}

	// Add max label.
	var tr = $j("<tr>");
	this._maxLabel = $j("<td class='ia-legend-item ia-legend-label ia-gradient-legend-label'>");
	this._maxLabel.html(maxText);
	tr.append(this._maxLabel);
	this.$table.append(tr);

	// Add the gradient.
	var tr = $j("<tr>");
	var td = $j("<td class='ia-legend-item'>");
	tr.append(td);
	this.$table.append(tr);

	// We need to place the this._canvas in a div otherwise the positioning of the this._canvas doesnt work.
	var div = $j("<div class='ia-legend-symbol' style='width:"+cw+";height:"+ch+";'>"); 
	td.append(div);

	// Create a this._canvas to contain the gradient.
	this._canvas = document.createElement('canvas');
	this._canvas.width = cw;
	this._canvas.height = ch;
	div.append($j(this._canvas));
	this._context = this._canvas.getContext("2d");

	// Add min label.
	var tr = $j("<tr>");
	this._minLabel = $j("<td class='ia-legend-item ia-legend-label ia-gradient-legend-label'>");
	this._minLabel.html(minText);
	tr.append(this._minLabel);
	this.$table.append(tr);
};

/**
 * Renders the block legend.
 *
 * @method _renderBlock
 * @private
 */
ia.GradientLegend.prototype._renderBlock = function() 
{		
	if (this._context)
	{
		this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);
	
		// Draw the gradient.
		this._context.strokeStyle = this.style.strokeStyle;
		this._context.lineWidth = this.style.lineWidth;
		var colorList = this.thematic.numericClassifier.colorPalette.getColorList();
		
		// Draw the gradient.
		this._context.beginPath();
		ia.Shape.drawGradient(this._canvas, colorList, "bottomToTop");
		this._context.fill();
		this._context.stroke();
	}
};

/**
 * Renders the point legend.
 *
 * @method _renderPoint
 * @private
 */
ia.GradientLegend.prototype._renderPoint = function() 
{		
	if (this._context)
	{
		this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);
		
		var minSymbolSize =  Math.min(this.thematic.numericClassifier.sizePalette.minSize, 
						this.thematic.numericClassifier.sizePalette.maxSize);
		var maxSymbolSize =  Math.max(this.thematic.numericClassifier.sizePalette.minSize, 
						this.thematic.numericClassifier.sizePalette.maxSize);
		
		var cx = this._canvas.width / 2;
		var cy = this._canvas.height / 2; 
		
		this._context.strokeStyle = this.style.strokeStyle;
		this._context.lineWidth = this.style.lineWidth;
		
		this._context.beginPath();
			ia.Shape.draw(this.thematic.symbol, this._context, cx, cy, minSymbolSize);
		this._context.stroke();
		
		this._context.beginPath();
		
			ia.Shape.draw(this.thematic.symbol, this._context, cx, cy, maxSymbolSize);
		this._context.stroke();
		
		/*this._context.beginPath();
			this._context.moveTo(this._canvas.width/2, 0);
			this._context.lineTo(this._canvas.width/2, 5);
		this._context.stroke();
		
		this._context.beginPath();
			this._context.moveTo(this._canvas.width/2, ((this._canvas.height + minSymbolSize)/2));
			this._context.lineTo(this._canvas.width/2, this._canvas.height);
		this._context.stroke();*/
	}
};
 
/**
 * Highlights the legend.
 *
 * @method highlight
 * @param {String} id The id of the item.
 */
ia.GradientLegend.prototype.highlight = function(id) 
{	
	if (this._context && this.thematic)
	{
		var data = this.thematic.getData();
		var dataItem = data[id];
		if (dataItem)
		{
			var value = dataItem.legendClass.value;
			if (this.thematic.symbol === ia.Shape.SQUARE || this.thematic.symbol === ia.Shape.LINE) 
				this._highlightBlock(value);
			else 
				this._highlightPoint(value);
		}
	}
};

/**
 * Highlights the block legend
 *
 * @method _highlightBlock
 * @param {Number} value The value of the item.
 * @private
 */
ia.GradientLegend.prototype._highlightBlock = function(value) 
{	
	this._renderBlock();
	if (ia.isNumber(value))
	{
		this._context.strokeStyle = this.highlightColor;
		this._context.lineWidth = 3;

		var y = this._canvas.height - (((value - this._minValue) / (this._maxValue - this._minValue)) * this._canvas.height);
		this._context.beginPath();
		this._context.moveTo(1, y);
		this._context.lineTo(this._canvas.width - 1, y);
		this._context.stroke();
	}
};

/**
 * Highlights the point legend.
 *
 * @method _highlightPoint
 * @param {Number} value The value of the item.
 * @private
 */
ia.GradientLegend.prototype._highlightPoint = function(value) 
{	
	this._renderPoint();
	if (ia.isNumber(value))
	{
		var legendClass = this.thematic.getClass(value)
		if (legendClass !== undefined)
		{
			var cx = this._canvas.width / 2;
			var cy = this._canvas.height / 2; 

			this._context.fillStyle = legendClass.color;			
			this._context.beginPath();
				ia.Shape.draw(this.thematic.symbol, this._context, cx, cy, legendClass.size);
			this._context.fill();
		}
	}
};

/**
 * Clears all highlights.
 *
 * @method clearHighlight
 */
ia.GradientLegend.prototype.clearHighlight = function() 
{	
	if (this.thematic.symbol === ia.Shape.SQUARE || this.thematic.symbol === ia.Shape.LINE) 
		this._renderBlock(); 
	else this._renderPoint();
};

/**
 * Selects.
 *
 * @method select
 * @param {String} id The id of the item.
 */
ia.GradientLegend.prototype.select = function(id) {};

/**
 * Unselects.
 *
 * @method unselect
 * @param {String} id The id of the item.
 */
ia.GradientLegend.prototype.unselect = function(id) {};

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

/**
 * Hides the legend.
 *
 * @method hide
 */
ia.GradientLegend.prototype.hide = function()
{
	this.container.css("display", "none");
};

/**
 * Shows the legend.
 *
 * @method show
 */
ia.GradientLegend.prototype.show = function()
{
	this.container.css("display", "inline");
};