Skip to content

Instantly share code, notes, and snippets.

@liekkas
Created May 15, 2012 15:04
Show Gist options
  • Save liekkas/2702470 to your computer and use it in GitHub Desktop.
Save liekkas/2702470 to your computer and use it in GitHub Desktop.
FLEX:Matrix Component Row
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