<commit_before>/*
    Weave (Web-based Analysis and Visualization Environment)
    Copyright (C) 2008-2011 University of Massachusetts Lowell

    This file is a part of Weave.

    Weave is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License, Version 3,
    as published by the Free Software Foundation.

    Weave 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 Weave.  If not, see <http://www.gnu.org/licenses/>.
*/

package weave.visualization.plotters
{	
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;
	
	import weave.Weave;
	import weave.api.WeaveAPI;
	import weave.api.data.IQualifiedKey;
	import weave.api.newDisposableChild;
	import weave.api.primitives.IBounds2D;
	import weave.api.registerLinkableChild;
	import weave.api.ui.IPlotTask;
	import weave.api.ui.IPlotter;
	import weave.api.ui.ITextPlotter;
	import weave.core.LinkableBoolean;
	import weave.core.LinkableHashMap;
	import weave.core.LinkableNumber;
	import weave.data.AttributeColumns.BinnedColumn;
	import weave.data.AttributeColumns.ColorColumn;
	import weave.data.KeySets.KeySet;
	import weave.primitives.Bounds2D;
	import weave.primitives.ColorRamp;
	import weave.utils.BitmapText;
	import weave.utils.LinkableTextFormat;
	import weave.visualization.plotters.styles.SolidFillStyle;
	import weave.visualization.plotters.styles.SolidLineStyle;

	/**
	 * AnchorPlotter
	 * @author kmanohar
	 */	
	public class AnchorPlotter extends AbstractPlotter implements ITextPlotter
	{
		public function AnchorPlotter()	
		{
			registerLinkableChild(this, LinkableTextFormat.defaultTextFormat); // this causes a redraw when text format changes
			registerLinkableChild(this, Weave.defaultColorColumn);			
			setSingleKeySource(_keySet);
		}
		
		public function setRadViz(radviz:IPlotter):void
		{
			if (this._radviz)
				throw new Error("radviz plotter may only be set once.");
			_radviz = radviz;
			if (radviz is RadVizPlotter)
				anchors = (radviz as RadVizPlotter).anchors;
			if (radviz is CompoundRadVizPlotter)
				anchors = (radviz as CompoundRadVizPlotter).anchors;
			if (!anchors)
				throw new Error("not a radviz plotter");
			this.anchors = registerSpatialProperty(anchors);
			this.anchors.childListCallbacks.addGroupedCallback(this, handleAnchorsChange, true);
			spatialCallbacks.triggerCallbacks();
		}
		private var _radviz:IPlotter;
		private var anchors:LinkableHashMap = null;
		
		public const labelAngleRatio:LinkableNumber = registerSpatialProperty(new LinkableNumber(0, verifyLabelAngleRatio));
		
		private const _keySet:KeySet = newDisposableChild(this, KeySet);
		private const tempPoint:Point = new Point();
		private const _bitmapText:BitmapText = new BitmapText();
		private var coordinate:Point = new Point();//reusable object
		public const enableWedgeColoring:LinkableBoolean = registerLinkableChild(this, new LinkableBoolean(false), fillColorMap);
		public const colorMap:ColorRamp = registerLinkableChild(this, new ColorRamp(ColorRamp.getColorRampXMLByName("Doppler Radar")),fillColorMap);
		public var anchorColorMap:Dictionary;
		
		
		public var drawingClassLines:Boolean = false;//this divides the circle into sectors which represent classes (number of sectors = number of classes)

		// anchorClasses key is String, value is array of AnchorPoint names
		public var anchorClasses:Dictionary = null;//this tells us the classes to which dimensional anchors belong to

		public var anchorThreshold:Number;
		public var doCDLayout:Boolean = false;// this displays the tstat value with every dimensional anchor name (displayed only when CD layout is done)
		
		private function getClassFromAnchor(anchorName:String):String
		{
			for (var key:String in anchorClasses)
			{
				var anchors:Array = anchorClasses[key];
				if (anchors.indexOf(anchorName) >= 0)
					return key;
			}
			return null;
		}
		
		//Fill this hash map with bounds of every record key for efficient look up in getDataBoundsFromRecordKey
		private var keyBoundsMap:Dictionary = new Dictionary();
		private const _currentScreenBounds:Bounds2D = new Bounds2D();
		private const _currentDataBounds:Bounds2D = new Bounds2D();
		
		public const circleLineStyle:SolidLineStyle = registerLinkableChild(this, new SolidLineStyle());
		public const anchorLineStyle:SolidLineStyle = registerLinkableChild(this, new SolidLineStyle());
		public const anchorFillStyle:SolidFillStyle = registerLinkableChild(this, new SolidFillStyle());
		public const anchorRadius:LinkableNumber = registerLinkableChild(this, new LinkableNumber(5));
		
		
		
		public function handleAnchorsChange():void
		{
			var keys:Array = anchors.getNames(AnchorPoint);
			var keyArray:Array = WeaveAPI.QKeyManager.getQKeys(ANCHOR_KEYTYPE,keys);

			_keySet.replaceKeys(keyArray);
			fillColorMap();
		}
		
		private static const ANCHOR_KEYTYPE:String = 'dimensionAnchors';
		
		
		
		private function fillColorMap():void
		{
			anchorColorMap = new Dictionary(true);
			var _names:Array = anchors.getNames(AnchorPoint);
			for (var i:int = 0; i < _names.length; i++)
				anchorColorMap[_names[i]] = colorMap.getColorFromNorm(i / (_names.length - 1)); 
		}
		
		override public function drawPlotAsyncIteration(task:IPlotTask):Number
		{
			drawAll(task.recordKeys, task.dataBounds, task.screenBounds, task.buffer);
			return 1;
		}
		private function drawAll(recordKeys:Array, dataBounds:IBounds2D, screenBounds:IBounds2D, destination:BitmapData):void
		{
			var x:Number; 
			var y:Number;
			
			var anchor:AnchorPoint;
			var radians:Number;
			keyBoundsMap = new Dictionary();

			var graphics:Graphics = tempShape.graphics;
			graphics.clear();
									
			
			for each(var key:IQualifiedKey in recordKeys)
			{
				anchor = anchors.getObject(key.localName) as AnchorPoint;
				if (key.keyType != ANCHOR_KEYTYPE || !anchor)
					continue;
				
				anchorLineStyle.beginLineStyle(null, graphics);
				anchorFillStyle.beginFillStyle(null, graphics);

				if(anchorThreshold)
				{
					if(anchor.classDiscriminationMetric.value < anchorThreshold)
						continue;
					
				}
				
				x = anchor.x.value;
				y = anchor.y.value;
				radians = anchor.polarRadians.value;
				var radius:Number = anchor.radius.value;
				
				var cos:Number = Math.cos(radians);
				var sin:Number = Math.sin(radians);
				
				tempPoint.x = radius * cos;
				tempPoint.y = radius * sin;
				dataBounds.projectPointTo(tempPoint, screenBounds);
				
				// draw circle
				if(enableWedgeColoring.value)
					graphics.beginFill(anchorColorMap[key.localName]);
				else if (doCDLayout)
				{
					//color the dimensional anchors according to the class hey belong to
					var classStr:String = getClassFromAnchor(key.localName);
					var cc:ColorColumn = Weave.defaultColorColumn;
					var binColumn:BinnedColumn = cc.getInternalColumn() as BinnedColumn;
					var binIndex:int = binColumn.getBinIndexFromDataValue(classStr);
					var color:Number = cc.ramp.getColorFromNorm(binIndex / (binColumn.numberOfBins - 1));
					if (isFinite(color))
						graphics.beginFill(color);<commit_msg>adding line that was mistakenly removed in previous commit<commit_after>/*
    Weave (Web-based Analysis and Visualization Environment)
    Copyright (C) 2008-2011 University of Massachusetts Lowell

    This file is a part of Weave.

    Weave is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License, Version 3,
    as published by the Free Software Foundation.

    Weave 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 Weave.  If not, see <http://www.gnu.org/licenses/>.
*/

package weave.visualization.plotters
{	
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;
	
	import weave.Weave;
	import weave.api.WeaveAPI;
	import weave.api.data.IQualifiedKey;
	import weave.api.newDisposableChild;
	import weave.api.primitives.IBounds2D;
	import weave.api.registerLinkableChild;
	import weave.api.ui.IPlotTask;
	import weave.api.ui.IPlotter;
	import weave.api.ui.ITextPlotter;
	import weave.core.LinkableBoolean;
	import weave.core.LinkableHashMap;
	import weave.core.LinkableNumber;
	import weave.data.AttributeColumns.BinnedColumn;
	import weave.data.AttributeColumns.ColorColumn;
	import weave.data.BinningDefinitions.CategoryBinningDefinition;
	import weave.data.KeySets.KeySet;
	import weave.primitives.Bounds2D;
	import weave.primitives.ColorRamp;
	import weave.utils.BitmapText;
	import weave.utils.LinkableTextFormat;
	import weave.visualization.plotters.styles.SolidFillStyle;
	import weave.visualization.plotters.styles.SolidLineStyle;

	/**
	 * AnchorPlotter
	 * @author kmanohar
	 */	
	public class AnchorPlotter extends AbstractPlotter implements ITextPlotter
	{
		public function AnchorPlotter()	
		{
			registerLinkableChild(this, LinkableTextFormat.defaultTextFormat); // this causes a redraw when text format changes
			registerLinkableChild(this, Weave.defaultColorColumn);			
			setSingleKeySource(_keySet);
		}
		
		public function setRadViz(radviz:IPlotter):void
		{
			if (this._radviz)
				throw new Error("radviz plotter may only be set once.");
			_radviz = radviz;
			if (radviz is RadVizPlotter)
				anchors = (radviz as RadVizPlotter).anchors;
			if (radviz is CompoundRadVizPlotter)
				anchors = (radviz as CompoundRadVizPlotter).anchors;
			if (!anchors)
				throw new Error("not a radviz plotter");
			this.anchors = registerSpatialProperty(anchors);
			this.anchors.childListCallbacks.addGroupedCallback(this, handleAnchorsChange, true);
			spatialCallbacks.triggerCallbacks();
		}
		private var _radviz:IPlotter;
		private var anchors:LinkableHashMap = null;
		
		public const labelAngleRatio:LinkableNumber = registerSpatialProperty(new LinkableNumber(0, verifyLabelAngleRatio));
		
		private const _keySet:KeySet = newDisposableChild(this, KeySet);
		private const tempPoint:Point = new Point();
		private const _bitmapText:BitmapText = new BitmapText();
		private var coordinate:Point = new Point();//reusable object
		public const enableWedgeColoring:LinkableBoolean = registerLinkableChild(this, new LinkableBoolean(false), fillColorMap);
		public const colorMap:ColorRamp = registerLinkableChild(this, new ColorRamp(ColorRamp.getColorRampXMLByName("Doppler Radar")),fillColorMap);
		public var anchorColorMap:Dictionary;
		
		
		public var drawingClassLines:Boolean = false;//this divides the circle into sectors which represent classes (number of sectors = number of classes)

		// anchorClasses key is String, value is array of AnchorPoint names
		public var anchorClasses:Dictionary = null;//this tells us the classes to which dimensional anchors belong to

		public var anchorThreshold:Number;
		public var doCDLayout:Boolean = false;// this displays the tstat value with every dimensional anchor name (displayed only when CD layout is done)
		
		private function getClassFromAnchor(anchorName:String):String
		{
			for (var key:String in anchorClasses)
			{
				var anchors:Array = anchorClasses[key];
				if (anchors.indexOf(anchorName) >= 0)
					return key;
			}
			return null;
		}
		
		//Fill this hash map with bounds of every record key for efficient look up in getDataBoundsFromRecordKey
		private var keyBoundsMap:Dictionary = new Dictionary();
		private const _currentScreenBounds:Bounds2D = new Bounds2D();
		private const _currentDataBounds:Bounds2D = new Bounds2D();
		
		public const circleLineStyle:SolidLineStyle = registerLinkableChild(this, new SolidLineStyle());
		public const anchorLineStyle:SolidLineStyle = registerLinkableChild(this, new SolidLineStyle());
		public const anchorFillStyle:SolidFillStyle = registerLinkableChild(this, new SolidFillStyle());
		public const anchorRadius:LinkableNumber = registerLinkableChild(this, new LinkableNumber(5));
		
		
		
		public function handleAnchorsChange():void
		{
			var keys:Array = anchors.getNames(AnchorPoint);
			var keyArray:Array = WeaveAPI.QKeyManager.getQKeys(ANCHOR_KEYTYPE,keys);

			_keySet.replaceKeys(keyArray);
			fillColorMap();
		}
		
		private static const ANCHOR_KEYTYPE:String = 'dimensionAnchors';
		
		
		
		private function fillColorMap():void
		{
			anchorColorMap = new Dictionary(true);
			var _names:Array = anchors.getNames(AnchorPoint);
			for (var i:int = 0; i < _names.length; i++)
				anchorColorMap[_names[i]] = colorMap.getColorFromNorm(i / (_names.length - 1)); 
		}
		
		override public function drawPlotAsyncIteration(task:IPlotTask):Number
		{
			drawAll(task.recordKeys, task.dataBounds, task.screenBounds, task.buffer);
			return 1;
		}
		private function drawAll(recordKeys:Array, dataBounds:IBounds2D, screenBounds:IBounds2D, destination:BitmapData):void
		{
			var x:Number; 
			var y:Number;
			
			var anchor:AnchorPoint;
			var radians:Number;
			keyBoundsMap = new Dictionary();

			var graphics:Graphics = tempShape.graphics;
			graphics.clear();
									
			
			for each(var key:IQualifiedKey in recordKeys)
			{
				anchor = anchors.getObject(key.localName) as AnchorPoint;
				if (key.keyType != ANCHOR_KEYTYPE || !anchor)
					continue;
				
				anchorLineStyle.beginLineStyle(null, graphics);
				anchorFillStyle.beginFillStyle(null, graphics);

				if(anchorThreshold)
				{
					if(anchor.classDiscriminationMetric.value < anchorThreshold)
						continue;
					
				}
				
				x = anchor.x.value;
				y = anchor.y.value;
				radians = anchor.polarRadians.value;
				var radius:Number = anchor.radius.value;
				
				var cos:Number = Math.cos(radians);
				var sin:Number = Math.sin(radians);
				
				tempPoint.x = radius * cos;
				tempPoint.y = radius * sin;
				dataBounds.projectPointTo(tempPoint, screenBounds);
				
				// draw circle
				if(enableWedgeColoring.value)
					graphics.beginFill(anchorColorMap[key.localName]);
				else if (doCDLayout)
				{
					//color the dimensional anchors according to the class hey belong to
					var classStr:String = getClassFromAnchor(key.localName);
					var cc:ColorColumn = Weave.defaultColorColumn;
					var binColumn:BinnedColumn = cc.getInternalColumn() as BinnedColumn;
					binColumn.binningDefinition.requestLocalObject(CategoryBinningDefinition, false)
					var binIndex:int = binColumn.getBinIndexFromDataValue(classStr);
					var color:Number = cc.ramp.getColorFromNorm(binIndex / (binColumn.numberOfBins - 1));
					if (isFinite(color))
						graphics.beginFill(color);
{'fraction_non_alphanumeric': 0.08420425982272788, 'fraction_numerical': 0.0031750231512104776, 'mean_word_length': 4.376600284495021, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5830420', 'n_tokens_mistral': 5248, 'n_tokens_neox': 4433, 'n_words': 1163}