Created
May 15, 2012 15:04
-
-
Save liekkas/2702470 to your computer and use it in GitHub Desktop.
FLEX:Matrix Component Row
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package | |
{ | |
import flash.utils.Dictionary; | |
import mx.containers.HBox; | |
import mx.containers.Tile; | |
import mx.containers.VBox; | |
/*************************************************************\ | |
* 矩阵行 | |
* | |
* @author liekkas.zeng | |
* @since 2012-5-10 20:48:31 | |
\*************************************************************/ | |
public class MatrixRow extends HBox | |
{ | |
/** | |
* 允许空行存在 | |
* */ | |
public var allowEmptyRow:Boolean = true; | |
protected var hGap:int = 2; | |
protected var vGap:int = 2; | |
/** | |
* 设置5个级别的数组,按顺序排序,为什么不采用排序算法来处理,因为在数量比较少的情况下,这种蛮力方法效率高 | |
* */ | |
private var l1Arr:Array = []; | |
private var l2Arr:Array = []; | |
private var l3Arr:Array = []; | |
private var l4Arr:Array = []; | |
private var l5Arr:Array = []; | |
/** | |
* 保存tile所在的hbox | |
* */ | |
protected var tileMap:Object = new Object(); | |
/** | |
* 一行能放下的item个数 | |
* */ | |
protected var maxNum:int = 0; | |
/** | |
* 第一个item | |
* */ | |
private var firstItem:MatrixItem; | |
/** | |
* 是否展示全部 | |
* */ | |
private var isMore:Boolean; | |
public function MatrixRow() | |
{ | |
super(); | |
this.percentWidth = 100; | |
this.setStyle("horizontalGap",1); | |
this.setStyle("verticalGap",1); | |
} | |
protected var _dataXML:XML; | |
protected var dataChanged:Boolean; | |
/** | |
* 计算出放了这么多item后,每个item能分配到得空留长度是多少 | |
* */ | |
private var bonusWidth:Number; | |
public function set dataXML(value:XML):void | |
{ | |
_dataXML = value; | |
dataChanged = true; | |
invalidateDisplayList(); | |
} | |
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void | |
{ | |
super.updateDisplayList(unscaledWidth,unscaledHeight); | |
if(dataChanged) | |
{ | |
dataChanged = false; | |
parse(_dataXML); | |
} | |
} | |
protected function parse(xml:XML):void | |
{ | |
if(xml) | |
{ | |
firstItem = new MatrixItem(); | |
firstItem.item = convertXML2Item(xml); | |
this.addChild(firstItem); | |
var vbox1:VBox = new VBox(); | |
vbox1.setStyle("horizontalGap",hGap); | |
vbox1.setStyle("verticalGap",vGap); | |
var miH:Number = 0; | |
var numEmptyRow:int = 0; | |
for each(var x:XML in xml.children()) | |
{ | |
var hbox1:HBox = new HBox(); | |
hbox1.setStyle("horizontalGap",hGap); | |
hbox1.setStyle("verticalGap",vGap); | |
var mi2:MatrixItem = new MatrixItem(); | |
mi2.item = convertXML2Item(x); | |
hbox1.addChild(mi2); | |
var tile:Tile = new Tile(); | |
tile.width = this.width - firstItem.width - mi2.width - hGap*2; | |
tile.percentHeight = 100; | |
tile.setStyle("horizontalGap",hGap); | |
tile.setStyle("verticalGap",vGap); | |
//计算出tile里面最多一行可以放多少个item | |
maxNum = Math.floor(tile.width / (MatrixItem.DEFAULT_WIDTH + hGap)); | |
//计算出放了这么多item后,每个item能分配到得空留长度是多少 | |
bonusWidth = (tile.width - MatrixItem.DEFAULT_WIDTH * maxNum)/maxNum - hGap; | |
//计算高度 | |
var tileH:Number = MatrixItem.DEFAULT_HEIGHT; | |
cleanLevelArr(); | |
for each(var i:XML in x.children()) | |
{ | |
var mi3:MatrixItem = new MatrixItem(); | |
mi3.item = convertXML2Item(i); | |
mi3.width += bonusWidth; | |
putLevelArr(mi3); | |
} | |
//当是空行时 | |
if(!allowEmptyRow) | |
{ | |
if(x.children().length() == 0) | |
{ | |
tileH = 0; | |
numEmptyRow ++; | |
hbox1.visible = hbox1.includeInLayout = allowEmptyRow; | |
} | |
} | |
addChildSorted(tile); | |
hbox1.addChild(tile); | |
tileMap[String(x.@id)] = hbox1; | |
vbox1.addChild(hbox1); | |
mi2.height = tileH; | |
miH += tileH; | |
} | |
this.addChild(vbox1); | |
firstItem.height= miH + (xml.children().length() - 1 - numEmptyRow) * vGap; | |
} | |
} | |
protected function convertXML2Item(xml:XML):Object | |
{ | |
var result:Object = new Object(); | |
result['name'] = xml.@name; | |
result['severity'] = xml.@severity; | |
result['id'] = xml.@id; | |
return result; | |
} | |
protected function cleanLevelArr():void | |
{ | |
l1Arr = []; | |
l2Arr = []; | |
l3Arr = []; | |
l4Arr = []; | |
l5Arr = []; | |
} | |
/** | |
* 分组 | |
* */ | |
protected function putLevelArr(mi:MatrixItem):void | |
{ | |
var severity:String = mi.item['severity']; | |
switch(severity) | |
{ | |
case "0": | |
l5Arr.push(mi); | |
break; | |
case "1": | |
l1Arr.push(mi); | |
break; | |
case "2": | |
l2Arr.push(mi); | |
break; | |
case "3": | |
l3Arr.push(mi); | |
break; | |
case "4": | |
l4Arr.push(mi); | |
break; | |
} | |
} | |
/** | |
* 添加item,默认只呈现第一排 | |
* */ | |
protected function addChildSorted(tile:Tile):void | |
{ | |
var sortArr:Array = [l1Arr,l2Arr,l3Arr,l4Arr,l5Arr]; | |
/** | |
* 计数器,如果达到了一行最多排放的个数,后面的隐藏起来 | |
* 注意:后面的也要添加进来,当发生告警时,有可能后面的出来一条一级告警,这时它会移到最前面 | |
* */ | |
var count:int = 0; | |
for each(var arr:Array in sortArr) | |
{ | |
for each(var item:MatrixItem in arr) | |
{ | |
item.visible = item.includeInLayout = count < maxNum; | |
tile.addChild(item); | |
count ++; | |
} | |
} | |
var obj:Object = new Object(); | |
obj['l1num'] = l1Arr.length; | |
obj['l2num'] = l2Arr.length; | |
obj['l3num'] = l3Arr.length; | |
obj['l4num'] = l4Arr.length; | |
obj['l5num'] = l5Arr.length; | |
tile.data = obj; | |
} | |
/** | |
* 更新状态,并更改顺序 | |
* */ | |
public function update(item:Object):void | |
{ | |
var pid:String = item['pid2']; | |
var id:String = item['id']; | |
var severity:String = item['severity']; | |
var tile:Tile = HBox(tileMap[pid]).getChildAt(1) as Tile; | |
var total:int = tile.numChildren; | |
for(var i:int=0;i < total ;i++) | |
{ | |
var mi:MatrixItem = tile.getChildAt(i) as MatrixItem; | |
if(mi.item['id'] == id) | |
{ | |
var oldSeverity:String = mi.item['severity']; | |
if(oldSeverity != severity) | |
{ | |
var obj:Object = tile.data; | |
var l1num:int = obj['l1num']; | |
var l2num:int = obj['l2num']; | |
var l3num:int = obj['l3num']; | |
var l4num:int = obj['l4num']; | |
var l5num:int = obj['l5num']; | |
var insertIndex:int; | |
switch(severity) | |
{ | |
case "1": | |
insertIndex = 0; | |
break; | |
case "2": | |
insertIndex = l1num; | |
break; | |
case "3": | |
insertIndex = l1num + l2num; | |
break; | |
case "4": | |
insertIndex = l1num + l2num + l3num; | |
break; | |
default: | |
insertIndex = l1num + l2num + l3num + l4num; | |
break; | |
} | |
/** | |
* 需要注意,如果告警级别变低,需要-1,因为原来的数组减少了当前这个Item | |
* */ | |
if(Number(oldSeverity)!= 0 && | |
Number(oldSeverity) < Number(severity)) | |
{ | |
insertIndex --; | |
} | |
mi.item['severity'] = severity; | |
mi.update(); | |
tile.addChildAt(mi,insertIndex); | |
judgeTile(tile,isMore); | |
} | |
else | |
{ | |
return; | |
} | |
} | |
} | |
} | |
/** | |
* 添加一条数据 | |
* */ | |
public function addItem(item:Object):void | |
{ | |
var pid:String = item['pid2']; | |
var id:String = item['id']; | |
var severity:String = item['severity']; | |
var tile:Tile = HBox(tileMap[pid]).getChildAt(1) as Tile; | |
var total:int = tile.numChildren; | |
var obj:Object = tile.data; | |
var l1num:int = obj['l1num']; | |
var l2num:int = obj['l2num']; | |
var l3num:int = obj['l3num']; | |
var l4num:int = obj['l4num']; | |
var l5num:int = obj['l5num']; | |
var mi3:MatrixItem = new MatrixItem(); | |
mi3.item = item; | |
mi3.width += bonusWidth; | |
var insertIndex:int; | |
switch(severity) | |
{ | |
case "1": | |
insertIndex = 0; | |
obj['l1num'] = ++l1num; | |
break; | |
case "2": | |
insertIndex = l1num; | |
obj['l2num'] = ++l2num; | |
break; | |
case "3": | |
insertIndex = l1num + l2num; | |
obj['l3num'] = ++l3num; | |
break; | |
case "4": | |
insertIndex = l1num + l2num + l3num; | |
obj['l4num'] = ++l4num; | |
break; | |
default: | |
insertIndex = l1num + l2num + l3num + l4num; | |
obj['l5num'] = ++l5num; | |
break; | |
} | |
tile.addChildAt(mi3,insertIndex); | |
//添加操作时,肯定有值,这个呈现出来 | |
HBox(tileMap[pid]).visible = HBox(tileMap[pid]).includeInLayout = true; | |
if(tile.numChildren > maxNum) | |
{ | |
moreSingle(HBox(tileMap[pid]),true); | |
} | |
else | |
{ | |
moreSingle(HBox(tileMap[pid]),false); | |
} | |
} | |
/** | |
* 删除一条 | |
* */ | |
public function delItem(item:Object):void | |
{ | |
var pid:String = item['pid2']; | |
var id:String = item['id']; | |
var tile:Tile = HBox(tileMap[pid]).getChildAt(1) as Tile; | |
var total:int = tile.numChildren; | |
for(var i:int=0;i < total ;i++) | |
{ | |
var mi:MatrixItem = tile.getChildAt(i) as MatrixItem; | |
if(mi.item['id'] == id) | |
{ | |
var obj:Object = tile.data; | |
var l1num:int = obj['l1num']; | |
var l2num:int = obj['l2num']; | |
var l3num:int = obj['l3num']; | |
var l4num:int = obj['l4num']; | |
var l5num:int = obj['l5num']; | |
switch(mi.item['severity'].toString()) | |
{ | |
case "1": | |
obj['l1num'] = --l1num; | |
break; | |
case "2": | |
obj['l2num'] = --l2num; | |
break; | |
case "3": | |
obj['l3num'] = --l3num; | |
break; | |
case "4": | |
obj['l4num'] = --l4num; | |
break; | |
default: | |
obj['l5num'] = --l5num; | |
break; | |
} | |
tile.removeChildAt(i); | |
if(tile.numChildren < maxNum) | |
{ | |
if(!allowEmptyRow) | |
{ | |
HBox(tileMap[pid]).visible = HBox(tileMap[pid]).includeInLayout = tile.numChildren > 0; | |
} | |
callLater(moreSingle,[HBox(tileMap[pid]),false]); | |
} | |
else | |
callLater(moreSingle,[HBox(tileMap[pid]),true]); | |
return; | |
} | |
} | |
} | |
/** | |
* 更多 | |
* */ | |
public function more(flag:Boolean):void | |
{ | |
isMore = flag; | |
var rowHeight:Number = 0; | |
var count:int = 0; | |
var numEmptyRow:int = 0; | |
for(var key:String in tileMap) | |
{ | |
count ++; | |
var tile:Tile = Tile(HBox(tileMap[key]).getChildAt(1)); | |
var len:int = tile.numChildren; | |
for(var i:int=maxNum;i<len;i++) | |
{ | |
var mi:MatrixItem = MatrixItem(tile.getChildAt(i)); | |
mi.visible = mi.includeInLayout = flag; | |
} | |
if(flag) | |
{ | |
tile.height = (MatrixItem.DEFAULT_HEIGHT + vGap) * Math.ceil((len / maxNum)) - vGap; | |
} | |
else | |
{ | |
tile.height = MatrixItem.DEFAULT_HEIGHT; | |
} | |
var item:MatrixItem = MatrixItem(HBox(tileMap[key]).getChildAt(0)); | |
if(!allowEmptyRow) | |
{ | |
if(tile.numChildren == 0) | |
{ | |
tile.height = 0; | |
numEmptyRow ++; | |
HBox(tileMap[key]).visible = HBox(tileMap[key]).includeInLayout = false; | |
} | |
else | |
{ | |
HBox(tileMap[key]).visible = HBox(tileMap[key]).includeInLayout = true; | |
} | |
} | |
else | |
{ | |
tile.height = tile.numChildren == 0 ? MatrixItem.DEFAULT_HEIGHT : tile.height; | |
} | |
item.height = tile.height; | |
rowHeight += tile.height; | |
} | |
firstItem.height = rowHeight + (count - 1 - numEmptyRow) * vGap; | |
} | |
/** | |
* 对单个tile进行操作 | |
* */ | |
protected function moreSingle(hbox:HBox,flag:Boolean):void | |
{ | |
isMore = flag; | |
var rowHeight:Number = 0; | |
var tile:Tile = Tile(hbox.getChildAt(1)); | |
var oldHeight:Number = tile.height; | |
var len:int = tile.numChildren; | |
for(var i:int=maxNum;i<len;i++) | |
{ | |
var mi:MatrixItem = MatrixItem(tile.getChildAt(i)); | |
mi.visible = mi.includeInLayout = flag; | |
} | |
if(flag) | |
{ | |
tile.height = (MatrixItem.DEFAULT_HEIGHT + vGap) * Math.ceil((len / maxNum)) - vGap; | |
} | |
else | |
{ | |
tile.height = MatrixItem.DEFAULT_HEIGHT; | |
} | |
if(!allowEmptyRow) | |
{ | |
if(tile.numChildren == 0) | |
{ | |
tile.height = -vGap; | |
hbox.visible = hbox.includeInLayout = false; | |
} | |
else | |
{ | |
hbox.visible = hbox.includeInLayout = true; | |
} | |
} | |
MatrixItem(hbox.getChildAt(0)).height = tile.height; | |
//计算出tile前后变化的高度 | |
rowHeight = tile.height - oldHeight; | |
firstItem.height += rowHeight; | |
} | |
/** | |
* 审视tile,是否显示全部 | |
* */ | |
protected function judgeTile(tile:Tile,flag:Boolean):void | |
{ | |
var count:int = 0; | |
var total:int = tile.numChildren; | |
for(var i:int=0;i < total ;i++) | |
{ | |
var mi:MatrixItem = tile.getChildAt(i) as MatrixItem; | |
mi.visible = mi.includeInLayout = flag ? true : count < maxNum; | |
count ++; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment