src/it/ht/rcs/console/entities/view/LinkView.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:VGroup 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:maps="com.google.maps.*"
xmlns:graph="it.ht.rcs.console.entities.view.graph.*"
xmlns:entities="it.ht.rcs.console.entities.view.*"
xmlns:renderers="it.ht.rcs.console.entities.view.renderers.*"
xmlns:components="it.ht.rcs.console.entities.view.components.*"
xmlns:filters="it.ht.rcs.console.entities.view.filters.*"
xmlns:utils="it.ht.rcs.console.utils.*"
height="100%"
width="100%"
creationComplete="onCreationComplete()"
addedToStage="onAddedToStage(event)"
removedFromStage="onRemovedFromStage(event)" >
<fx:Script>
<![CDATA[
import fr.kapit.layouts.model.Edge;
import it.ht.rcs.console.entities.controller.EntityManager;
import it.ht.rcs.console.entities.model.Entity;
import it.ht.rcs.console.entities.model.Flow;
import it.ht.rcs.console.entities.model.Flows;
import it.ht.rcs.console.entities.view.components.advanced.timeline.TimelineUtils;
import it.ht.rcs.console.entities.view.renderers.CustomLink;
import it.ht.rcs.console.events.FilterEvent;
import it.ht.rcs.console.search.controller.SearchManager;
import locale.R;
import mx.collections.ArrayCollection;
import mx.collections.ListCollectionView;
import mx.core.FlexGlobals;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import spark.collections.Sort;
[Bindable]
public var entities:ListCollectionView;
[Bindable]
public var section:EntitiesSection;
[Bindable]
public var entitiesToShow:ArrayCollection;
private var numEntitiesToShow:int=0;
private var currentIndex:int=0;
private var roots:ArrayCollection;
[Bindable]
public var selectedNodes:ArrayCollection;
[Bindable]
public var selectedEdge:Object
[Bindable]
public var linkEnabled:Boolean;
[Bindable]
public var mergeEnabled:Boolean;
[Bindable]
public var jumpEnabled:Boolean;
[Bindable]
public var exportEnabled:Boolean;
[Bindable]
public var groupEnabled:Boolean;
[Bindable]
public var ungroupEnabled:Boolean;
private var sort:Sort;
private var xmlData:XML;
[Bindable]
private var startDate:Date;
[Bindable]
private var endDate:Date;
[Bindable]
public var actionbar:EntitiesActionBar;
private var flows:ArrayCollection;
public var inited:Boolean; //??
private var drawing:Boolean
[Embed(source='/img/NEW/dottedLine.png')]
public static const dottedLine:Class;
[Embed(source='/img/NEW/dashedLine.png')]
public static const dashedLine:Class;
[Embed(source='/img/NEW/fullLine.png')]
public static const fullLine:Class;
[Bindable]
public var filterCriteria:Object=
{
type:[],
relevance:[],
time:"time",
from:"lastMonth",
to:0,
programs:[]
};
private function onCreationComplete():void
{
//trace("LINK MAP: CREATION COMPLETE")
startDate=new Date();
startDate.time=startDate.time - (1000 * 60 * 60 * 24 * 30);
endDate=new Date();
}
public function draw():void
{
graph.visible=false;
graph.zoom(1)
zoomSlider.value=1
if(!entitiesToShow)
entitiesToShow=new ArrayCollection()
entitiesToShow.removeAll()
for (var i:int=0; i < entities.length; i++)
{
var entity:Entity=entities.getItemAt(i) as Entity; //TODO : ADD FILTERS
if(meetsCriteria(entity))
entitiesToShow.addItem(entity)
}
graph.draw(entitiesToShow, filterCriteria)
graph.visible=true; //event listener?
// trace("Drawing Graph > Entities to show: "+entitiesToShow.length)
getFlows(entitiesToShow) //TODO
}
private function meetsCriteria(entity:Entity):Boolean
{
if(!entity)
return false;
if(entity.type=="group")
return true;
if(filterCriteria.type)
{
if(filterCriteria.type.length >0 && filterCriteria.type.indexOf(entity.type)==-1)
return false;
}
return true;
}
protected function onAddedToStage(event:Event):void
{
// trace("LINK MAP: ADDED TO STAGE")
filterCriteria={ type:[],
relevance:[],
time:"time",
from:"lastMonth",
to:0,
programs:[]
}
FlexGlobals.topLevelApplication.dispatchEvent(new FilterEvent(FilterEvent.ENTITIES_FILTER_RESET))
}
protected function onRemovedFromStage(event:Event):void
{
trace("LINK MAP: REMOVED FROM STAGE")
}
public function addListeners():void
{
//trace("LINK MAP: ADD LISTENERS")
FlexGlobals.topLevelApplication.addEventListener(FilterEvent.ENTITIES_FILTER_CHANGED, onFilterChange)
}
public function removeListeners():void
{
//trace("LINK MAP: REMOVE LISTENERS")
FlexGlobals.topLevelApplication.removeEventListener(FilterEvent.ENTITIES_FILTER_CHANGED, onFilterChange)
}
protected function onElementDoubleClick():void
{
if(graph.vis.selection[graph.vis.selection.length - 1] is CustomLink)
{
var entity1:Entity=EntityManager.instance.getItem(graph.vis.selection[graph.vis.selection.length - 1].data.source) as Entity
var entity2:Entity=EntityManager.instance.getItem(graph.vis.selection[graph.vis.selection.length - 1].data.target) as Entity
if (graph.vis.selection[graph.vis.selection.length - 1].data.info && graph.vis.selection[graph.vis.selection.length - 1].data.level=="automatic" && (entity1.type=="target" || entity2.type=="target"))
actionbar.jumpToEvidence()
return;
}
var item:*=EntityManager.instance.getItem(graph.vis.selection[graph.vis.selection.length - 1].data._id) //last selected
if (item)
{
var hasPermission:Boolean=SearchManager.instance.getItem(item.stand_for)
if(item.type=="group") // && !hasPermission) uncomment to jump to other operation graph (update the EntitiesSectionStateManager)
return;
section.stateManager.manageItemSelection(item);
}
}
public function onSelectionChange():void
{
//trace("VIS SELECTION CHANGED")
actionbar.selectedObject=null
actionbar.selectedObjects=null;
info.selectedItem=null;
info.selectedItems=null;
linkEnabled=actionbar.linkEnabled=false;
mergeEnabled=actionbar.mergeEnabled=false;
jumpEnabled=actionbar.jumpEnabled=false;
exportEnabled=actionbar.exportEnabled=true;
groupEnabled=actionbar.groupEnabled=false;
ungroupEnabled=actionbar.ungroupEnabled=false;
if(!graph.selection)
return
//Only 1 node
if (graph.selection.length == 1 && graph.selection[0].data.name)
{
info.selectedItem=EntityManager.instance.getItem(String(graph.selection[0].data._id)) || new Entity(graph.selection[0].data)
info.selectedItems=new <Object>[info.selectedItem];
actionbar.selectedObject=info.selectedItem;
actionbar.selectedObjects=new <Object>[actionbar.selectedObject];
actionbar.selectedObjects.push(actionbar.selectedObject)
}
//Only 1 edge
else if (graph.selection.length == 1 && graph.selection[0].data.versus != null)
{
info.selectedItem=graph.selection[0].data
info.selectedItems=new <Object>[info.selectedItem];
actionbar.selectedObject=info.selectedItem;
actionbar.selectedObjects=new <Object>[actionbar.selectedObject];
actionbar.selectedObjects.push(actionbar.selectedObject)
var entity1:Entity=EntityManager.instance.getItem(graph.selection[0].data.source) as Entity
var entity2:Entity=EntityManager.instance.getItem(graph.selection[0].data.target) as Entity
if (graph.selection[0].data.info && (graph.selection[0].data.type == "peer" || graph.selection[0].data.type == "know" || graph.selection[0].data.type == "position") && graph.selection[0].data.level == "automatic" && (entity1.type=="target" || entity2.type=="target"))//TODO!!!!!!!!!!!
jumpEnabled=actionbar.jumpEnabled=true;
}
//merging enabled?
else if (graph.selection.length == 2)
{
trace("linked: " + areLinked(graph.selection[0].data._id, graph.selection[1].data._id))
actionbar.selectedObjects=new Vector.<Object>
actionbar.selectedObjects.push(graph.selection[0].data)
actionbar.selectedObjects.push(graph.selection[1].data)
if (graph.selection[0].data.name && graph.selection[1].data.name)
linkEnabled=actionbar.linkEnabled=true;
if ((graph.selection[0].data.type == "person" && graph.selection[1].data.type == "person") || (graph.selection[0].data.type == "target" && graph.selection[1].data.type == "person") || (graph.selection[0].data.type == "person" && graph.selection[1].data.type == "target"))
{
mergeEnabled=actionbar.mergeEnabled=true;
}
}
//grouping
var i:int
if (graph.selection.length > 1)
{
groupEnabled=actionbar.groupEnabled=true;
for(i=0;i<graph.selection.length;i++)
{
if(!graph.selection[i].data.name || (graph.selection[i].data.name && graph.selection[i].data.type=="group") || (graph.selection[i].data.name && isGrouped(graph.selection[i].data._id)))
{
groupEnabled=actionbar.groupEnabled=false;
break;
}
}
}
if (graph.selection.length == 1 && graph.selection[0].data.type=="group" && !graph.selection[0].data.stand_for)
{
ungroupEnabled=actionbar.ungroupEnabled=true;
}
//no selection do not enable export
if (graph.selection.length < 1)
exportEnabled=actionbar.exportEnabled=false;
else
{ //check if there is a link object in selection
for ( i=0; i < graph.selection.length; i++)
{
if (!graph.selection[i].data.name || (graph.selection[i].data.type=="group" && !SearchManager.instance.getItem(graph.selection[i].data.stand_for))) //link has no name
exportEnabled=actionbar.exportEnabled=false; //link in selection do not enable export
}
}
}
private function onFilterChange(e:FilterEvent):void
{
/*
trace("==============================")
trace("FILTER HAS CHANGED")
trace("==============================")
trace("time: "+filterCriteria.time)
trace("from: "+filterCriteria.from)
trace("to: "+filterCriteria.to)
trace("type: "+filterCriteria.type)
trace("tag: "+filterCriteria.relevance)
*/
if(filterCriteria.from=="lastMonth")
{
startDate=new Date();
startDate.time=startDate.time - (1000 * 60 * 60 * 24 * 30);
endDate=new Date();
}
else if(filterCriteria.from=="last3Months")
{
startDate=new Date();
startDate.time=startDate.time - (1000 * 60 * 60 * 24 * 90);
endDate=new Date();
}
else if(filterCriteria.from=="last6Months")
{
startDate=new Date();
startDate.time=startDate.time - (1000 * 60 * 60 * 24 * 180);
endDate=new Date();
}
else if(filterCriteria.from && filterCriteria.to)
{
startDate=new Date(filterCriteria.from*1000)
endDate=new Date(filterCriteria.from*1000);
}
// trace("from: "+startDate)
// trace("to: "+endDate)
if(timeline.initialized)
{
timeline.stop()
timeline.startDate=startDate
timeline.endDate=endDate
timeline.update()
//onAddedToStage(null);
}
draw()
}
private function isGrouped(entityId:String):Boolean
{
for(var i:int=0;i<entities.length;i++)
{
var entity:Entity=entities.getItemAt(i) as Entity
if(entity.type=="group" && entity.children.source.indexOf(entityId)!=-1)
return true;
}
return false;
}
private function areLinked(source:String, target:String):Boolean
{
var edge:Edge;
var renderer:CustomLink
for (var i:int=0; i < graph.vis.graph.edges.length; i++)
{
edge=graph.vis.graph.edges[i] as Edge
renderer=edge.visualEdge as CustomLink
if ((renderer.data.source == source && renderer.data.target == target) || (renderer.data.source == target && renderer.data.target == source))
return true;
}
return false;
}
private function getFlows(entities:ListCollectionView):void
{
timeline.visible=false;
trace("get flows")
if (!entities)
return;
var ids:Array=new Array();
flows=new ArrayCollection
for (var i:int=0; i < entities.length; i++)
{
var e:Entity=entities.getItemAt(i) as Entity;
ids.push(e._id)
}
EntityManager.instance.flow(ids, formatDate(startDate), formatDate(endDate), onFlowResult, onFlowFault)
}
private function formatDate(d:Date):String
{
if (!d)
return "";
return String(d.fullYear) + TimelineUtils.doubleDigits(d.month + 1) + TimelineUtils.doubleDigits(d.date);
}
private function onFlowResult(e:ResultEvent):void
{
//trace("flow result")
timeline.visible=true;
flows=e.result as ArrayCollection;
timeline.highlight(flows);
graph.visible=true;
if(section.linkToHighLight)
{
graph.highlightLink(section.linkToHighLight.from, section.linkToHighLight.to)
}
if(section.nodeToHighLight)
{
graph.highlightNode(section.nodeToHighLight.id)
}
}
private function onFlowFault(e:FaultEvent):void
{
timeline.visible=true;
graph.visible=true;
//trace("flow fault")
}
private function onTimelineChange():void
{
// trace("LINK MAP: TIMELINE CHANGE")
var d:Date=new Date();
d.time=timeline.slider.value;
var formattedDate:String=String(d.fullYear) + TimelineUtils.doubleDigits(d.month + 1) + TimelineUtils.doubleDigits(d.date);
var currentEdge:Edge;
var currentRenderer:CustomLink;
if (graph.vis)
{
for (var r:int=0; r < graph.vis.graph.edges.length; r++)
{
currentEdge=graph.vis.graph.edges[r] as Edge;
currentRenderer=currentEdge.visualEdge as CustomLink
currentRenderer.reset()
}
}
if (flows)
{
for (var i:int=0; i < flows.length; i++)
{
var flow:Flow=flows[i] as Flow;
if (flow.date == formattedDate)
{
for (var j:int=0; j < flow.flows.length; j++)
{
var f:Flows=flow.flows.getItemAt(j) as Flows;
if (graph.vis)
{
for (var k:int=0; k < graph.vis.graph.edges.length; k++)
{
currentEdge=graph.vis.graph.edges[k] as Edge;
currentRenderer=currentEdge.visualEdge as CustomLink
if (currentRenderer.data.source == f.from && currentRenderer.data.target == f.rcpt || currentRenderer.data.source == f.rcpt && currentRenderer.data.target == f.from)
{
currentRenderer.showFlow(f.from, f.rcpt, f.count);
}
}
}
}
}
}
}
}
private function onZoom(e:Event):void
{
graph.zoom(e.currentTarget.value)
}
]]>
</fx:Script>
<s:HGroup width="100%"
height="100%"
gap="5">
<s:VGroup width="100%"
height="100%">
<s:HGroup verticalAlign="middle"
horizontalAlign="right"
width="100%"
paddingTop="6" gap="-1">
<renderers:FilterRenderer label="{R.get('TIMEFRAME')}" filter="{filterCriteria}" property="time"
popupFactory="it.ht.rcs.console.entities.view.filters.DateFilterPopup"
width="150" />
<renderers:FilterRenderer label="{R.get('TYPE_ENTITY')}" filter="{filterCriteria}" property="type"
popupFactory="it.ht.rcs.console.entities.view.filters.TypeFilterPopup"
width="150"/>
<renderers:FilterRenderer label="{R.get('TYPE_LINK')}" property="programs" filter="{filterCriteria}"
popupFactory="it.ht.rcs.console.entities.view.filters.LinkTypeFilterPopup"
width="150"/>
<renderers:FilterRenderer label="{R.get('RELEVANCE')}" property="relevance" filter="{filterCriteria}"
popupFactory="it.ht.rcs.console.entities.view.filters.TagFilterPopup"
width="150"/>
<s:Spacer width="100%"/>
<s:Label text="zoom: " fontWeight="bold"/>
<s:Spacer width="10"/>
<s:HSlider id="zoomSlider"
maximum="10" minimum="0.1"
showDataTip="false"
value="1"
stepSize="0.1" change="onZoom(event)"/>
</s:HGroup>
<s:Line width="100%">
<s:stroke>
<s:SolidColorStroke color="0xCCCCCC"/>
</s:stroke>
</s:Line>
<s:BorderContainer id="graphCnvs"
borderColor="#CCCCCC"
backgroundColor="#FFFFFF"
width="100%"
height="100%">
<graph:LinkGraph id="graph"
selectionChange="onSelectionChange()"
elementDoubleClick="onElementDoubleClick()"/>
</s:BorderContainer>
<s:Line width="100%">
<s:stroke>
<s:SolidColorStroke color="0xCCCCCC"/>
</s:stroke>
</s:Line>
<components:Timeline width="100%"
id="timeline"
step="{Timeline.DAY}"
startDate="{startDate}"
endDate="{endDate}"
change="onTimelineChange()"/>
</s:VGroup>
<entities:EntityInfoPanel id="info"/>
</s:HGroup>
</s:VGroup>