Handling tabulated data

Tabulated data sources (generally CSV files) are organized in rows and columns using a String delimiter. At any given column and row index, a record value representing a data unit can be found (optionally delimited by a record Delimiter). The record has a row index and column index, typed as a String while it can represent a Date, a Number or other content. Visualizer handles parsing such data, reconstruction and data content interpretation via a set of options described below:

When performing data analysis and tabulated data parsing, Visualizer simplifies manipulating the generated data and the rendered graph via:

Simple Tabulated data integration

In the following example, we expose a simple approach to manipulate tabulated data input. Visualizer needs only the analysisPath and the csvDelimiter to correctly interpret the data input. In this example, we can notice that the nodeTooltipFields and nodeTooltipTitles have the same length of the analysisPath, as we make an index based correspondence between column reference in the analysisPath and the node tooltip array.
Note : It is not mandatory to have the same analysisPath length for nodeLabelFiels and nodeTooltipFields array. You can specify a unique array that will be used for all generated nodes.
Data Source Implementation code Output
Supervisor,Student
Mr.Hans,Mr.Andro
Mr.Bans,Mr.Bale
Mr.Andro,Mr.Waterloo
Mr.Sebastian,Mr.Andricks
Mr.Anani,Mr.Waterloo
Mr.Full,Mr.Sebastian
Mr.Andricks,Mr.Waterloo
Mr.Anani,Mr.Waterloo
Mr.Sebastian,Mr.Bale
Mr.Bans,Mr.Anani
<visualizer:Visualizer  id="visualizer"
	width="100%" height="100%"
	layout="forceDirected"
	analysisPath="{['Supervisor','Student']}"
	csvDelimiter=","
	nodeLabelFields="id"
	nodeTooltipFields="{['id','columnReference'],['id','columnReference']}"
	creationComplete="visualizer_creationCompleteHandler(event)"/>

Advanced data pre-processing for Tabulated data

Tabulated data is a very common format of communication and storage. The content of such data is generally raw and basic and thus cannot be transformed easily to extract some important information. As Visualizer support such data format, it was important to provide some tools to perform pre-processing for tabulated data in order to show the desired information in a comprehensive graph. Among these tools : The following data source represents a basic CSV where we describe the activity summary of a given company (named MyCompany) :
Entreprise;Departement;Operational Field;Name;Age;Work days;Total days
MyCompany;Building A;Law;UID1;39;20;30
MyCompany;Building A;Law;UID2;30;20;30
MyCompany;Building A;Law;UID3;37;22;30
MyCompany;Building A;Design;UID4;26;22;30
MyCompany;Building A;Design;UID5;23;19;30
MyCompany;Building A;Design;UID6;27;20;30
MyCompany;Building C;Web;UID7;19;15;30
MyCompany;Building C;Web;UID8;23;15;30
MyCompany;Building C;Web;UID9;27;20;30
MyCompany;Building C;Web;UID10;23;20;30
MyCompany;Building C;Research;UID11;27;21;30
MyCompany;Building C;Research;UID12;27;20;30
MyCompany;Building C;Research;UID13;28;20;30
MyCompany;Building B;QA;UID14;27;20;30
MyCompany;Building B;QA;UID15;25;20;30
MyCompany;Building B;QA;UID16;23;20;30
MyCompany;Building B;Management;UID17;52;23;30
MyCompany;Building B;Management;UID18;51;22;30
MyCompany;Building B;Management;UID19;50;22;30
MyCompany;Building B;Marketing;UID20;32;20;30
MyCompany;Building B;Marketing;UID21;31;20;30
MyCompany;Building B;Marketing;UID22;33;24;30
The visualization need is to represent a hierarchy displaying the enterprise with its building with their operational fields and employees. The additional need is to show for each building, operational field or employee the mean age and the holidays number. As you can conclude, the holidays records should be generated based on the working days and total days. Such needs are perfectly handled via Visualizer parsing options. The following snippet includes all aspects of tabulated data advanced parsing.
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" 
			   xmlns:visualizer="fr.kapit.visualizer.*"
			   minWidth="955" minHeight="600" xmlns:descriptor="fr.kapit.data.descriptor.*">
	<fx:Script>
		<![CDATA[
			import fr.kapit.data.utils.ReportingUtils;
			import fr.kapit.layouts.constants.EdgeDrawType;
			
			import mx.events.FlexEvent;
			
			[Embed(source="entrepriseSummary.csv",mimeType="application/octet-stream")]
			private var entrepriseDataSource:Class;
			
			protected function visualizer_creationCompleteHandler(event:FlexEvent):void
			{
				var byteArray:ByteArray;
				byteArray = new entrepriseDataSource() as ByteArray; // a entrepriseDataSource loaded csv file as byteArray
				
				initTabulatedConfiguration();
				visualizer.dataProvider=byteArray.readUTFBytes(byteArray.length);
				visualizer.hierarchicalTreeLayout.edgeDrawing = EdgeDrawType.ORTHOGONAL_CURVED_POLYLINE;
			}
			
			private var reportingFunctions:Dictionary;
			/**
			 * Intialize table parsing parameters
			 */
			protected function initTabulatedConfiguration():void
			{
				//Creating a new column named Holidays based on 'Work days' and 'Total days' columns and on a merging function. The merging function enables filling the
				//new created Holidays column with adequate records based on merging columns' records.
				mergeDescriptor.addMergeDescription(mergeEntity);
				//Specifying generated data properties of each column.
				attributesDescriptor.addAttributesDescription(entrepriseAttributesEntity);
				attributesDescriptor.addAttributesDescription(nameAttributesEntity);
				attributesDescriptor.addAttributesDescription(depAttributesEntity);	
				//Specifying how rows are merged when creating a given data unit. The function is applied on records of a given column.
				// Example : when creating the data unit corresponding to MyCompany (column 'Entreprise'), all rows are merged as the id is present in all rows. Those for each column merging
				// will be based on the the reporting function of each column. In that case, the records of the 'age' column will be merged in one record corresponding to the mean of
				// all ages.
				reportingFunctions=new Dictionary();
				reportingFunctions["Age"]=ReportingUtils.mean;
				reportingFunctions["Holidays"]=ReportingUtils.mean;
				reportingFunctions["Total days"]=ReportingUtils.mean;
				reportingFunctions["Work days"]=ReportingUtils.mean;
				//Indicating parsing properties
				visualizer.mergeDescriptor=mergeDescriptor;
				visualizer.reportingFunctions=reportingFunctions;
			}
			/**
			 * Function used to merge records of work days and total days into holiday days.
			 */
			protected function mergeFunction(arr:Array):Number
			{
				if(arr.length!=2)
					return 0;
				var val1 : Number = Number(arr[0]);
				var val2:Number = Number(arr[1]);
				var value:Number = val2-val1;
				return Number(value.toFixed(2));
			}
		]]>
	</fx:Script>
	<fx:Declarations>
		<descriptor:MergeEntity id="mergeEntity" mergeColumns="{['Work days','Total days']}" mergeName="Holidays" mergeFunction="{mergeFunction}"/>
		<descriptor:MergeDescriptor id="mergeDescriptor" leaveMergeColumns="true"/>
		<descriptor:AttributesDescriptor id="attributesDescriptor"/>
		<descriptor:AttributesEntity id="entrepriseAttributesEntity" columnName="Entreprise" attributes="{['Holidays','Work days','Age']}" attributesNumber="3"/>
		<descriptor:AttributesEntity id="nameAttributesEntity" columnName="Name" attributes="{['Holidays','Age']}" attributesNumber="2"/>
		<descriptor:AttributesEntity id="depAttributesEntity" columnName="Departement" attributes="{['Holidays','Total days','Age']}" attributesNumber="3"/>
	</fx:Declarations>
	<visualizer:Visualizer  id="visualizer"
							width="100%" height="100%"
							layout="hierarchicalTree"
							nodeExpandButtonPlacement="midBottom"
							analysisPath="{['Entreprise','Departement','Operational Field','Name']}"
							csvDelimiter=";"
							nodeLabelFields="id"
							nodeTooltipFields="{['Age'],['Age','Holidays'],['Age','Holidays'],['Age','Holidays']}"
							nodeTooltipTitles="{['Age'],['Age','Holidays'],['Age','Holidays'],['Age','Holidays']}"
							creationComplete="visualizer_creationCompleteHandler(event)"
							/>
</s:Application>

The output of this implementation is: