最近公司用到Eco tree,感觉还不错,就贴出来跟大家分享,主要的功能是tree,但请注意,此tree非比tree,里面还有一个小tree,用于缩略图的效果。具体代码如下,不做过多解释:
主文件HTML
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ECOTree Advanced</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../../lib/jquery-ui/css/ui-lightness/jquery-ui-1.8.19.custom.css" type="text/css">
<script type="text/javascript" src="scripts/init-iframe.js"></script>
<script type="text/javascript" src="../../lib/jquery-ui/dev/jquery-1.7.2.js"></script>
<link type="text/css" rel="stylesheet" href="style/ECOTree.css" />
<link type="text/css" rel="stylesheet" href="../../style/all.css" />
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<style>v\:*{ behavior:url(#default#VML);}
</style>
</head>
<body style="height:2200px;">
<div style="width:99%;height:40px;font-size:9pt; background:#9CC;position:fixed;border:1px solid #EFEFEF;padding:3px;">
2011年1-8月累计运营收入<span class="editor_number_input" title="编辑" id="earning" name="运营收入">47.26</span>亿元,同比增长<span class="editor_number_input" title="编辑-同比增长" name="同比增长" id="currYearGrowthrate">3.57</span>%,较10年同期增幅下降<span class="editor_number_input" title="编辑" name="同期增幅" id="sametermGrowthrate">5.63</span>个百分点;增幅下降主要影响因素为通话收入,其变动影响度为<span class="editor_number_input" name="影响度" id="effectChangeDegree">-0.19</span>%;其中漫游通话收入和非漫游收入下降为主要因素…...
</div>
<div id="abbreviative" style="float:left;width:178px;height:88px;position:fixed; top: 58px;left:8px;border:1px #CCC solid; z-index: 1000; background:URL('img/bg.png');">
<iframe src="tree-mini.html" width="100%" height="86px" name="MyIFrame" id="MyIFrame" frameborder='no' scrolling="no" left="0" top="0"></iframe>
</div>
<div style="float:left;width:558px;height:36px; line-height:36px;border:1px solid #EFEFEF; position: fixed;top:58px;left:198px;padding-top:3px; background:URL('img/bg.png');">
<label>月份:</label>
<span>
<select class="ui-datepicker-year" id="datepicker-year" name="year">
<option>请选择年</option>
</select>
<select class="ui-datepicker-month" name="month">
<option>请选择月份</option>
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
<option value="04">4</option>
<option value="05">5</option>
<option value="06">6</option>
<option value="07">7</option>
<option value="08">8</option>
<option value="09">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12" selected="selected">12</option>
</select>
</span>
<label>地区:</label>
<span>
<select name="area" style="width:128px;">
</select>
</span>
<span id="search_btn" class="ui-state-default ui-corner-all">
<span class="ui-icon ui-icon-search"></span>
查询
</span>
<span id="release_btn" class="ui-state-default ui-corner-all">
<span class="ui-icon ui-icon-extlink"></span>
发布
</span>
</span>
</div>
<script type="text/javascript" src="scripts/app.js"></script>
<script type="text/javascript" src="scripts/ECOTree-1.1.js"></script>
<div id="sample1" style="clear: both;"></div>
<!--
<script type="text/javascript" src="scripts/init-page.js"></script>
-->
</body>
</html>
init-iframe.js
/**
* 新增加的功能:初始化参数,参数包括iframe的document和window,对于html,可以使用document操作,函数方法,可以使用window操作
*/
var ifDoc = null;
var ifWin = null;
initIframeParam = function(){
//console.log('进来 了?');
if (document.all){//IE
ifDoc = document.frames["MyIFrame"].document;
ifWin = document.getElementById("MyIFrame").contentWindow;
//alert('是这里吗?'+document.getElementById("MyIFrame").contentWindow.t);
}else{//Firefox
ifWin = document.getElementById('MyIFrame').contentWindow;
ifDoc = document.getElementById('MyIFrame').contentDocument || document.getElementById('MyIFrame').contentWindow.document;
}
}
scripts/app.js
var t = null;
/**
* 被 子窗口调用测试
*/
test = function(){
alert('子窗口调用父窗口方法成功!');
}
/**
*页面加载完后事件
*/
$(function(){
setNumberValueColor();
initSelectInput();
//初始化iframe
initIframeParam();
//初始树
doSearch();
//查询按钮单击后执行doSearch
$('#search_btn').click(doSearch);
//可编辑的数字双击后执行textfieldEditor
$('.editor_number_input').dblclick(textfieldEditor);
$('div').dblclick(selectedNode);
})
/**
* 设置样式,如果是数值,如果小于零,则设置为红色 ; 否则为绿色,或蓝色
* 设置遇到鼠标后的效果,移出鼠标后的效果
*/
setNumberValueColor = function(){
$('.editor_number_input').each(function(){
if($(this).text()<0){
$(this).css("color",'#F00');
}else{
$(this).css("color",'#0E0');
}
});
$(".editor_number_input").hover(
function () {
$(this).addClass("hover");
},
function () {
$(this).removeClass("hover");
}
);
}
/**
*执行编辑,
*首先查找当前已经处在编辑状态下的input,将其置为非编辑状态,其次,将本节点置为编辑状态,
*如果enter则验证、判断后再提交;暂缺数值组件与验证
*/
textfieldEditor = function(){
if($('.currentEditor').length>0){
var val = $('.currentEditor').val();
$('.currentEditor').parent().html(val);
}
var oldVal = $(this).text();
//一个表单,长度为当前取到的字符的长度3.14则为5
var inputNode = '<input class="currentEditor" type="text" value="'+oldVal+'" size="'+(oldVal.length*2.65)+'"/>';
$(this).html(inputNode);
//移除双击事件,只监听enter or ESC键
//$(this).unbind('dblclick');
//接收键盘事件
var newOldVal = "";
$("input").keydown(function(){
newOldVal=$('.currentEditor').val();
});
$(this).keyup( function() {
if(isNaN($('.currentEditor').val())){
//$('.currentEditor').val(newOldVal);
}
});
/* 小键盘45(-),46(.),48,49,50,51,52,53,54,55,56,57
*/
$(this).keypress(function(e) {
//console.warn(e.charCode);
if (e.keyCode == 13) {
if(!isNaN($('.currentEditor').val())){
$(this).text($('.currentEditor').val());
}else{
$(this).text(oldVal);
alert("ERROR\n输入的参数值非数字类型!");
$(this).focus();
}
}else if (e.keyCode == 27){
$(this).text(oldVal);
}
//$(".editor_number_input").bind("dblclick", textfieldEditor);
});
}
/**
*初始化select表单,年份应该是动态的,明年后年,还可以选择当年,月份是死的,只有12月
*/
initSelectInput = function(){
var d = new Date();
var byYear = d.getYear();
//var byMonth = d.getMonth()+1;
if(!document.all){
byYear+=1900;
}
for(var i=0;i<=15;i++){
var oldYear = byYear-i;
var optElement = $('<option value="'+oldYear+'">'+oldYear+'</option>');
if(i==0){
$(optElement).attr('selected','selected');
}
$("#datepicker-year").append(optElement);
}
$.ajax({
url:'../..//action/common/getAreaCombobox.action',
dataType:'json',
async: false,
success:function(response){
if(response.areas.length>0){
var obj = $('select[name="area"]').html('');
for(var o in response.areas){
var n = response.areas[o].id;
var node = $('<option value='+n.areaCode+'>'+n.areaName+'</option>');
if(n.areaName=="天津分公司"){
$(node).attr('selected','selected');
}
$(obj).append(node);
}
}
}
});
}
/**
*初始化树,查询树数据,都在此方法
*/
doSearch = function(){
var d = new Date();
var byMonth = d.getMonth()+1;
var yNode = $('#datepicker-year');
var byYear = d.getYear();
var mNode = $('select[name="month"]');
var areaNode = $('select[name="area"]');
var pyear = $(yNode).val();
if(!document.all){
byYear=Number(Number(byYear)+1900);
}
var pmonth= $(mNode).val();
if(pyear==byYear&&pmonth>byMonth){
pmonth = byMonth;
}
//console.warn($(areaNode).val());
//alert($(yNode).val()+"-"+$(mNode).val()+" / "+$(areaNode).val());
$.ajax({
url:'../../action/eco/getEcoTreeDate.action',
type:'POST',
async: false,
data:{
areaCode:$(areaNode).val(),
year:pyear,
month:pmonth
},
success:function(msg){
//数据成功了,需要重装装载eco tree,并将缩略图的数据也重新装载
//console.dir(msg.list);
t = new ECOTree('t','sample1');
$(msg.list).each(function(){
//console.log(this.incomeId,this.parentId,this.title);
var currYearGrowthrate = '<span class="currYearGrowthrate">同比'+this.currYearGrowthrate+'</span>';
var sametermGrowthrate = '<span class="sametermGrowthrate">同期增幅'+this.sametermGrowthrate+'</span>';
var effectChangeDegree = '<span class="effectChangeDegree">变动影响指数'+this.effectChangeDegree+'</span>';
if(this.incomeId=='001'){
//console.dir(this);
$('#earning').html(this.currYearIncome);
$('#currYearGrowthrate').html(this.currYearGrowthrate.replace('%',''));
$('#sametermGrowthrate').html(this.sametermGrowthrate.replace('%',''));
$('#effectChangeDegree').html(this.effectChangeDegree.replace('%',''));
t.add(this.incomeId,-1,this.title+"<br/>"+currYearGrowthrate+sametermGrowthrate,null,null,"green","black");
}else{
t.add(this.incomeId,this.parentId,this.title+"<br/>"+currYearGrowthrate+sametermGrowthrate+effectChangeDegree);
}
});
t.UpdateTree();
setNumberValueColor();
}
})
}
/*查询节点*/
function ChangeSearchMode() {
var mode = parseInt(document.forms[0].searchMode.value);
t.config.searchMode = mode;
}
/*节点选择模式*/
function ChangeSelMode() {
var mode = parseInt(document.forms[0].selMode.value);
t.config.selectMode = mode;
t.unselectAll();
}
/*输出选择的节点*/
function selectedNode(node) {
console.dir($(node));
}
/*输出选择的节点
function selectedNodes() {
var selnodes = t.getSelectedNodes();
var s = [];
for (var n = 0; n < selnodes.length; n++){
s.push('' + n + ': Id=' + selnodes[n].id + ', Title='+ selnodes[n].dsc + ', Metadata='+ selnodes[n].meta + '\n');
}
alert('The selected nodes are:\n\n' + ((selnodes.length >0) ? s.join(''): 'None.'));
}*/
/**
*检测滚动条的座标,并设置iframe内容移动
*/
function ScollPostion() {//滚动条位置
var tt, ll, ww, hh;
if (document.documentElement && document.documentElement.scrollTop) {
tt = document.documentElement.scrollTop;
ll = document.documentElement.scrollLeft;
ww = document.documentElement.scrollWidth;
hh = document.documentElement.scrollHeight;
} else if (document.body) {
tt = document.body.scrollTop;
ll = document.body.scrollLeft;
ww = document.body.scrollWidth;
hh = document.body.scrollHeight;
}
//console.log(tt, ll, ww, hh);
var sam = ifDoc.getElementById('sample1');
//设置iframe的sample1的属性
sam.scrollTop = tt/10;
sam.scrollLeft = ll/10;
}
/**
*监听滚动条
*/
var timeout = false;
$(window).scroll(function(){
if (timeout){
clearTimeout(timeout);
}
timeout = setTimeout(function(){
ScollPostion();
},100);
});
ECOTree-1.1.js
/*-------------------------------------------------------------------------------------------
| ECOTree.js
ECONode = function (id, pid, dsc, w, h, c, bc, target, meta) {
this.id = id;
this.pid = pid;
this.dsc = dsc;
this.w = w;
this.h = h;
this.c = c;
this.bc = bc;
this.target = target;
this.meta = meta;
this.siblingIndex = 0;
this.dbIndex = 0;
this.XPosition = 0;
this.YPosition = 0;
this.prelim = 0;
this.modifier = 0;
this.leftNeighbor = null;
this.rightNeighbor = null;
this.nodeParent = null;
this.nodeChildren = [];
this.isCollapsed = false;
this.canCollapse = false;
this.isSelected = false;
}
ECONode.prototype._getLevel = function () {
if (this.nodeParent.id == -1) {
return 0;
}
else return this.nodeParent._getLevel() + 1;
}
ECONode.prototype._isAncestorCollapsed = function () {
if (this.nodeParent.isCollapsed) {
return true;
} else {
if (this.nodeParent.id == -1) {
return false;
} else {
return this.nodeParent._isAncestorCollapsed();
}
}
}
ECONode.prototype._setAncestorsExpanded = function () {
if (this.nodeParent.id == -1) {
return;
} else {
this.nodeParent.isCollapsed = false;
return this.nodeParent._setAncestorsExpanded();
}
}
ECONode.prototype._getChildrenCount = function () {
if (this.isCollapsed) return 0;
if(this.nodeChildren == null)
return 0;
else
return this.nodeChildren.length;
}
ECONode.prototype._getLeftSibling = function () {
if(this.leftNeighbor != null && this.leftNeighbor.nodeParent == this.nodeParent)
return this.leftNeighbor;
else
return null;
}
ECONode.prototype._getRightSibling = function () {
if(this.rightNeighbor != null && this.rightNeighbor.nodeParent == this.nodeParent)
return this.rightNeighbor;
else
return null;
}
ECONode.prototype._getChildAt = function (i) {
return this.nodeChildren[i];
}
ECONode.prototype._getChildrenCenter = function (tree) {
node = this._getFirstChild();
node1 = this._getLastChild();
return node.prelim + ((node1.prelim - node.prelim) + tree._getNodeSize(node1)) / 2;
}
ECONode.prototype._getFirstChild = function () {
return this._getChildAt(0);
}
ECONode.prototype._getLastChild = function () {
return this._getChildAt(this._getChildrenCount() - 1);
}
ECONode.prototype._drawChildrenLinks = function (tree) {
var s = [];
var xa = 0, ya = 0, xb = 0, yb = 0, xc = 0, yc = 0, xd = 0, yd = 0;
var node1 = null;
switch(tree.config.iRootOrientation)
{
case ECOTree.RO_TOP:
xa = this.XPosition + (this.w / 2);
ya = this.YPosition + this.h;
break;
case ECOTree.RO_BOTTOM:
xa = this.XPosition + (this.w / 2);
ya = this.YPosition;
break;
case ECOTree.RO_RIGHT:
xa = this.XPosition;
ya = this.YPosition + (this.h / 2);
break;
case ECOTree.RO_LEFT:
xa = this.XPosition + this.w;
ya = this.YPosition + (this.h / 2);
break;
}
for (var k = 0; k < this.nodeChildren.length; k++)
{
node1 = this.nodeChildren[k];
switch(tree.config.iRootOrientation)
{
case ECOTree.RO_TOP:
xd = xc = node1.XPosition + (node1.w / 2);
yd = node1.YPosition;
xb = xa;
switch (tree.config.iNodeJustification)
{
case ECOTree.NJ_TOP:
yb = yc = yd - tree.config.iLevelSeparation / 2;
break;
case ECOTree.NJ_BOTTOM:
yb = yc = ya + tree.config.iLevelSeparation / 2;
break;
case ECOTree.NJ_CENTER:
yb = yc = ya + (yd - ya) / 2;
break;
}
break;
case ECOTree.RO_BOTTOM:
xd = xc = node1.XPosition + (node1.w / 2);
yd = node1.YPosition + node1.h;
xb = xa;
switch (tree.config.iNodeJustification)
{
case ECOTree.NJ_TOP:
yb = yc = yd + tree.config.iLevelSeparation / 2;
break;
case ECOTree.NJ_BOTTOM:
yb = yc = ya - tree.config.iLevelSeparation / 2;
break;
case ECOTree.NJ_CENTER:
yb = yc = yd + (ya - yd) / 2;
break;
}
break;
case ECOTree.RO_RIGHT:
xd = node1.XPosition + node1.w;
yd = yc = node1.YPosition + (node1.h / 2);
yb = ya;
switch (tree.config.iNodeJustification)
{
case ECOTree.NJ_TOP:
xb = xc = xd + tree.config.iLevelSeparation / 2;
break;
case ECOTree.NJ_BOTTOM:
xb = xc = xa - tree.config.iLevelSeparation / 2;
break;
case ECOTree.NJ_CENTER:
xb = xc = xd + (xa - xd) / 2;
break;
}
break;
case ECOTree.RO_LEFT:
xd = node1.XPosition;
yd = yc = node1.YPosition + (node1.h / 2);
yb = ya;
switch (tree.config.iNodeJustification)
{
case ECOTree.NJ_TOP:
xb = xc = xd - tree.config.iLevelSeparation / 2;
break;
case ECOTree.NJ_BOTTOM:
xb = xc = xa + tree.config.iLevelSeparation / 2;
break;
case ECOTree.NJ_CENTER:
xb = xc = xa + (xd - xa) / 2;
break;
}
break;
}
switch(tree.render)
{
case "CANVAS":
tree.ctx.save();
tree.ctx.strokeStyle = tree.config.linkColor;
tree.ctx.beginPath();
switch (tree.config.linkType)
{
case "M":
tree.ctx.moveTo(xa,ya);
tree.ctx.lineTo(xb,yb);
tree.ctx.lineTo(xc,yc);
tree.ctx.lineTo(xd,yd);
break;
case "B":
tree.ctx.moveTo(xa,ya);
tree.ctx.bezierCurveTo(xb,yb,xc,yc,xd,yd);
break;
}
tree.ctx.stroke();
tree.ctx.restore();
break;
case "VML":
switch (tree.config.linkType)
{
case "M":
s.push('<v:polyline points="');
s.push(xa + ' ' + ya + ' ' + xb + ' ' + yb + ' ' + xc + ' ' + yc + ' ' + xd + ' ' + yd);
s.push('" strokecolor="'+tree.config.linkColor+'"><v:fill on="false" /></v:polyline>');
break;
case "B":
s.push('<v:curve from="');
s.push(xa + ' ' + ya + '" control1="' + xb + ' ' + yb + '" control2="' + xc + ' ' + yc + '" to="' + xd + ' ' + yd);
s.push('" strokecolor="'+tree.config.linkColor+'"><v:fill on="false" /></v:curve>');
break;
}
break;
}
}
return s.join('');
}
ECOTree = function (obj, elm) {
this.config = {
iMaxDepth : 100,
iLevelSeparation : 60,
iSiblingSeparation : 60,
iSubtreeSeparation : 160,
iRootOrientation : ECOTree.RO_TOP,
iNodeJustification : ECOTree.NJ_TOP,
topXAdjustment : 0,
topYAdjustment : 0,
render : "AUTO",
linkType : "M",
linkColor : "blue",
nodeColor : "#CCCCFF",
nodeFill : ECOTree.NF_GRADIENT,
nodeBorderColor : "blue",
nodeSelColor : "#FFFFCC",
levelColors : ["#5555FF","#8888FF","#AAAAFF","#CCCCFF"],
levelBorderColors : ["#5555FF","#8888FF","#AAAAFF","#CCCCFF"],
colorStyle : ECOTree.CS_NODE,
useTarget : true,
searchMode : ECOTree.SM_DSC,
selectMode : ECOTree.SL_MULTIPLE,
defaultNodeWidth : 160,
defaultNodeHeight : 60,
defaultTarget : 'javascript:void(0);',
expandedImage : './img/less.gif',
collapsedImage : './img/plus.gif',
transImage : './img/trans.gif'
}
this.version = "1.1";
this.obj = obj;
this.elm = document.getElementById(elm);
this.self = this;
this.render = (this.config.render == "AUTO" ) ? ECOTree._getAutoRenderMode() : this.config.render;
this.ctx = null;
this.canvasoffsetTop = 0;
this.canvasoffsetLeft = 0;
this.maxLevelHeight = [];
this.maxLevelWidth = [];
this.previousLevelNode = [];
this.rootYOffset = 0;
this.rootXOffset = 0;
this.nDatabaseNodes = [];
this.mapIDs = {};
this.root = new ECONode(-1, null, null, 2, 2);
this.iSelectedNode = -1;
this.iLastSearch = 0;
}
//Constant values
//Tree orientation
ECOTree.RO_TOP = 0;
ECOTree.RO_BOTTOM = 1;
ECOTree.RO_RIGHT = 2;
ECOTree.RO_LEFT = 3;
//Level node alignment
ECOTree.NJ_TOP = 0;
ECOTree.NJ_CENTER = 1;
ECOTree.NJ_BOTTOM = 2;
//Node fill type
ECOTree.NF_GRADIENT = 0;
ECOTree.NF_FLAT = 1;
//Colorizing style
ECOTree.CS_NODE = 0;
ECOTree.CS_LEVEL = 1;
//Search method: Title, metadata or both
ECOTree.SM_DSC = 0;
ECOTree.SM_META = 1;
ECOTree.SM_BOTH = 2;
//Selection mode: single, multiple, no selection
ECOTree.SL_MULTIPLE = 0;
ECOTree.SL_SINGLE = 1;
ECOTree.SL_NONE = 2;
ECOTree._getAutoRenderMode = function() {
var r = "VML";
var is_ie6 = /msie 6\.0/i.test(navigator.userAgent);
var is_ff = /Firefox/i.test(navigator.userAgent);
if (is_ff) r = "CANVAS";
return r;
}
//CANVAS functions...
ECOTree._roundedRect = function (ctx,x,y,width,height,radius) {
ctx.beginPath();
ctx.moveTo(x,y+radius);
ctx.lineTo(x,y+height-radius);
ctx.quadraticCurveTo(x,y+height,x+radius,y+height);
ctx.lineTo(x+width-radius,y+height);
ctx.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
ctx.lineTo(x+width,y+radius);
ctx.quadraticCurveTo(x+width,y,x+width-radius,y);
ctx.lineTo(x+radius,y);
ctx.quadraticCurveTo(x,y,x,y+radius);
ctx.fill();
ctx.stroke();
}
ECOTree._canvasNodeClickHandler = function (tree,target,nodeid) {
if (target != nodeid) return;
tree.selectNode(nodeid,true);
}
//Layout algorithm
ECOTree._firstWalk = function (tree, node, level) {
var leftSibling = null;
node.XPosition = 0;
node.YPosition = 0;
node.prelim = 0;
node.modifier = 0;
node.leftNeighbor = null;
node.rightNeighbor = null;
tree._setLevelHeight(node, level);
tree._setLevelWidth(node, level);
tree._setNeighbors(node, level);
if(node._getChildrenCount() == 0 || level == tree.config.iMaxDepth)
{
leftSibling = node._getLeftSibling();
if(leftSibling != null)
node.prelim = leftSibling.prelim + tree._getNodeSize(leftSibling) + tree.config.iSiblingSeparation;
else
node.prelim = 0;
}
else
{
var n = node._getChildrenCount();
for(var i = 0; i < n; i++)
{
var iChild = node._getChildAt(i);
ECOTree._firstWalk(tree, iChild, level + 1);
}
var midPoint = node._getChildrenCenter(tree);
midPoint -= tree._getNodeSize(node) / 2;
leftSibling = node._getLeftSibling();
if(leftSibling != null)
{
node.prelim = leftSibling.prelim + tree._getNodeSize(leftSibling) + tree.config.iSiblingSeparation;
node.modifier = node.prelim - midPoint;
ECOTree._apportion(tree, node, level);
}
else
{
node.prelim = midPoint;
}
}
}
ECOTree._apportion = function (tree, node, level) {
var firstChild = node._getFirstChild();
var firstChildLeftNeighbor = firstChild.leftNeighbor;
var j = 1;
for(var k = tree.config.iMaxDepth - level; firstChild != null && firstChildLeftNeighbor != null && j <= k;)
{
var modifierSumRight = 0;
var modifierSumLeft = 0;
var rightAncestor = firstChild;
var leftAncestor = firstChildLeftNeighbor;
for(var l = 0; l < j; l++)
{
rightAncestor = rightAncestor.nodeParent;
leftAncestor = leftAncestor.nodeParent;
modifierSumRight += rightAncestor.modifier;
modifierSumLeft += leftAncestor.modifier;
}
var totalGap = (firstChildLeftNeighbor.prelim + modifierSumLeft + tree._getNodeSize(firstChildLeftNeighbor) + tree.config.iSubtreeSeparation) - (firstChild.prelim + modifierSumRight);
if(totalGap > 0)
{
var subtreeAux = node;
var numSubtrees = 0;
for(; subtreeAux != null && subtreeAux != leftAncestor; subtreeAux = subtreeAux._getLeftSibling())
numSubtrees++;
if(subtreeAux != null)
{
var subtreeMoveAux = node;
var singleGap = totalGap / numSubtrees;
for(; subtreeMoveAux != leftAncestor; subtreeMoveAux = subtreeMoveAux._getLeftSibling())
{
subtreeMoveAux.prelim += totalGap;
subtreeMoveAux.modifier += totalGap;
totalGap -= singleGap;
}
}
}
j++;
if(firstChild._getChildrenCount() == 0)
firstChild = tree._getLeftmost(node, 0, j);
else
firstChild = firstChild._getFirstChild();
if(firstChild != null)
firstChildLeftNeighbor = firstChild.leftNeighbor;
}
}
ECOTree._secondWalk = function (tree, node, level, X, Y) {
if(level <= tree.config.iMaxDepth)
{
var xTmp = tree.rootXOffset + node.prelim + X;
var yTmp = tree.rootYOffset + Y;
var maxsizeTmp = 0;
var nodesizeTmp = 0;
var flag = false;
switch(tree.config.iRootOrientation)
{
case ECOTree.RO_TOP:
case ECOTree.RO_BOTTOM:
maxsizeTmp = tree.maxLevelHeight[level];
nodesizeTmp = node.h;
break;
case ECOTree.RO_RIGHT:
case ECOTree.RO_LEFT:
maxsizeTmp = tree.maxLevelWidth[level];
flag = true;
nodesizeTmp = node.w;
break;
}
switch(tree.config.iNodeJustification)
{
case ECOTree.NJ_TOP:
node.XPosition = xTmp;
node.YPosition = yTmp;
break;
case ECOTree.NJ_CENTER:
node.XPosition = xTmp;
node.YPosition = yTmp + (maxsizeTmp - nodesizeTmp) / 2;
break;
case ECOTree.NJ_BOTTOM:
node.XPosition = xTmp;
node.YPosition = (yTmp + maxsizeTmp) - nodesizeTmp;
break;
}
if(flag)
{
var swapTmp = node.XPosition;
node.XPosition = node.YPosition;
node.YPosition = swapTmp;
}
switch(tree.config.iRootOrientation)
{
case ECOTree.RO_BOTTOM:
node.YPosition = -node.YPosition - nodesizeTmp;
break;
case ECOTree.RO_RIGHT:
node.XPosition = -node.XPosition - nodesizeTmp;
break;
}
if(node._getChildrenCount() != 0)
ECOTree._secondWalk(tree, node._getFirstChild(), level + 1, X + node.modifier, Y + maxsizeTmp + tree.config.iLevelSeparation);
var rightSibling = node._getRightSibling();
if(rightSibling != null)
ECOTree._secondWalk(tree, rightSibling, level, X, Y);
}
}
ECOTree.prototype._positionTree = function () {
this.maxLevelHeight = [];
this.maxLevelWidth = [];
this.previousLevelNode = [];
ECOTree._firstWalk(this.self, this.root, 0);
switch(this.config.iRootOrientation)
{
case ECOTree.RO_TOP:
case ECOTree.RO_LEFT:
this.rootXOffset = this.config.topXAdjustment + this.root.XPosition;
this.rootYOffset = this.config.topYAdjustment + this.root.YPosition;
break;
case ECOTree.RO_BOTTOM:
case ECOTree.RO_RIGHT:
this.rootXOffset = this.config.topXAdjustment + this.root.XPosition;
this.rootYOffset = this.config.topYAdjustment + this.root.YPosition;
}
ECOTree._secondWalk(this.self, this.root, 0, 0, 0);
}
ECOTree.prototype._setLevelHeight = function (node, level) {
if (this.maxLevelHeight[level] == null)
this.maxLevelHeight[level] = 0;
if(this.maxLevelHeight[level] < node.h)
this.maxLevelHeight[level] = node.h;
}
ECOTree.prototype._setLevelWidth = function (node, level) {
if (this.maxLevelWidth[level] == null)
this.maxLevelWidth[level] = 0;
if(this.maxLevelWidth[level] < node.w)
this.maxLevelWidth[level] = node.w;
}
ECOTree.prototype._setNeighbors = function(node, level) {
node.leftNeighbor = this.previousLevelNode[level];
if(node.leftNeighbor != null)
node.leftNeighbor.rightNeighbor = node;
this.previousLevelNode[level] = node;
}
ECOTree.prototype._getNodeSize = function (node) {
switch(this.config.iRootOrientation)
{
case ECOTree.RO_TOP:
case ECOTree.RO_BOTTOM:
return node.w;
case ECOTree.RO_RIGHT:
case ECOTree.RO_LEFT:
return node.h;
}
return 0;
}
ECOTree.prototype._getLeftmost = function (node, level, maxlevel) {
if(level >= maxlevel) return node;
if(node._getChildrenCount() == 0) return null;
var n = node._getChildrenCount();
for(var i = 0; i < n; i++)
{
var iChild = node._getChildAt(i);
var leftmostDescendant = this._getLeftmost(iChild, level + 1, maxlevel);
if(leftmostDescendant != null)
return leftmostDescendant;
}
return null;
}
ECOTree.prototype._selectNodeInt = function (dbindex, flagToggle) {
if (this.config.selectMode == ECOTree.SL_SINGLE)
{
if ((this.iSelectedNode != dbindex) && (this.iSelectedNode != -1))
{
this.nDatabaseNodes[this.iSelectedNode].isSelected = false;
}
this.iSelectedNode = (this.nDatabaseNodes[dbindex].isSelected && flagToggle) ? -1 : dbindex;
}
this.nDatabaseNodes[dbindex].isSelected = (flagToggle) ? !this.nDatabaseNodes[dbindex].isSelected : true;
}
ECOTree.prototype._collapseAllInt = function (flag) {
var node = null;
for (var n = 0; n < this.nDatabaseNodes.length; n++)
{
node = this.nDatabaseNodes[n];
if (node.canCollapse) node.isCollapsed = flag;
}
this.UpdateTree();
}
ECOTree.prototype._selectAllInt = function (flag) {
var node = null;
for (var k = 0; k < this.nDatabaseNodes.length; k++)
{
node = this.nDatabaseNodes[k];
node.isSelected = flag;
}
this.iSelectedNode = -1;
this.UpdateTree();
}
ECOTree.prototype._drawTree = function () {
var s = [];
var node = null;
var color = "";
var border = "";
for (var n = 0; n < this.nDatabaseNodes.length; n++)
{
node = this.nDatabaseNodes[n];
switch (this.config.colorStyle) {
case ECOTree.CS_NODE:
color = node.c;
border = node.bc;
break;
case ECOTree.CS_LEVEL:
var iColor = node._getLevel() % this.config.levelColors.length;
color = this.config.levelColors[iColor];
iColor = node._getLevel() % this.config.levelBorderColors.length;
border = this.config.levelBorderColors[iColor];
break;
}
if (!node._isAncestorCollapsed()){
switch (this.render){
case "CANVAS":
//Canvas part...
this.ctx.save();
this.ctx.strokeStyle = border;
switch (this.config.nodeFill) {
case ECOTree.NF_GRADIENT:
var lgradient = this.ctx.createLinearGradient(node.XPosition,0,node.XPosition+node.w,0);
lgradient.addColorStop(0.0,((node.isSelected)?this.config.nodeSelColor:color));
lgradient.addColorStop(1.0,"#F5FFF5");
this.ctx.fillStyle = lgradient;
break;
case ECOTree.NF_FLAT:
this.ctx.fillStyle = ((node.isSelected)?this.config.nodeSelColor:color);
break;
}
ECOTree._roundedRect(this.ctx,node.XPosition,node.YPosition,node.w,node.h,5);
this.ctx.restore();
//HTML part...
s.push('<div id="' + node.id + '" class="econode" style="{top:'+(node.YPosition+this.canvasoffsetTop)+'; left:'+(node.XPosition+this.canvasoffsetLeft)+'; width:'+node.w+'; height:'+node.h+';}" ');
/*if (this.config.selectMode != ECOTree.SL_NONE)
s.push('οnclick="javascript:ECOTree._canvasNodeClickHandler('+this.obj+',event.target.id,\''+node.id+'\');" '); */
s.push('>');
s.push('<font face=Verdana size=1>');
if (node.canCollapse) {
s.push('<a class="toggle" id="c' + node.id + '" onClick="'+this.obj+'.collapseNode(\''+node.id+'\', true)" >');
s.push('<img border="0" src="'+((node.isCollapsed) ? this.config.collapsedImage : this.config.expandedImage)+'" >');
s.push('</a>');
s.push('<img src="'+this.config.transImage+'" >');
}
if (node.target && this.config.useTarget) {
s.push('<a class="nodeDsc" id="t' + node.id + '" href="'+node.target+'">');
s.push(node.dsc);
s.push('</a>');
} else {
s.push(node.dsc);
}
s.push('</font>');
s.push('</div>');
break;
case "VML":
s.push('<v:roundrect id="' + node.id + '" strokecolor="'+border+'" arcsize="0.18" ');
s.push('style="position:absolute; top:'+node.YPosition+'; left:'+node.XPosition+'; width:'+node.w+'; height:'+node.h+'" ');
if (this.config.selectMode != ECOTree.SL_NONE)
s.push('href="javascript:'+this.obj+'.selectNode(\''+node.id+'\', true);" ');
s.push('>');
s.push('<v:textbox inset="0.5px,0.5px,0.5px,0.5px" ><font face=Verdana size=1>');
if (node.canCollapse) {
s.push('<a style="clear:both;position: absolute;bottom: -3px;left: 45%; z-index: 10000;" onClick="'+this.obj+'.collapseNode(\''+node.id+'\', true);" >');
s.push('<img border=0 src="'+((node.isCollapsed) ? this.config.collapsedImage : this.config.expandedImage)+'" >');
s.push('</a>');
s.push('<img src="'+this.config.transImage+'" >');
}
if (node.target && this.config.useTarget){
s.push('<a href="'+node.target+'">');
s.push(node.dsc);
s.push('</a>');
} else {
s.push(node.dsc);
}
s.push('</font></v:textbox>');
switch (this.config.nodeFill) {
case ECOTree.NF_GRADIENT:
s.push('<v:fill type=gradient color2="'+((node.isSelected)?this.config.nodeSelColor:color)+'" color="#F5FFF5" angle=90 />');
break;
case ECOTree.NF_FLAT:
s.push('<v:fill type="solid" color="'+((node.isSelected)?this.config.nodeSelColor:color)+'" />');
break;
}
s.push('<v:shadow type="single" on="true" opacity="0.7" />');
s.push('</v:roundrect>');
break;
}
if (!node.isCollapsed) s.push(node._drawChildrenLinks(this.self));
}
}
return s.join('');
}
ECOTree.prototype.toString = function () {
var s = [];
this._positionTree();
switch (this.render) {
case "CANVAS":
s.push('<canvas id="ECOTreecanvas" width="12600" height="6000"></canvas>');
break;
case "HTML":
s.push('<div class="maindiv">');
s.push(this._drawTree());
s.push('</div>');
break;
case "VML":
s.push('<v:group coordsize="5000, 5000" coordorigin="0, 0" style="position:absolute;width=5000px;height=5000px;" >');
s.push(this._drawTree());
s.push('</v:group>');
break;
}
return s.join('');
}
// ECOTree API begins here...
ECOTree.prototype.UpdateTree = function () {
this.elm.innerHTML = this;
if (this.render == "CANVAS") {
var canvas = document.getElementById("ECOTreecanvas");
if (canvas && canvas.getContext) {
this.canvasoffsetLeft = canvas.offsetLeft;
this.canvasoffsetTop = canvas.offsetTop;
this.ctx = canvas.getContext('2d');
var h = this._drawTree();
var r = this.elm.ownerDocument.createRange();
r.setStartBefore(this.elm);
var parsedHTML = r.createContextualFragment(h);
//this.elm.parentNode.insertBefore(parsedHTML,this.elm)
//this.elm.parentNode.appendChild(parsedHTML);
this.elm.appendChild(parsedHTML);
//this.elm.insertBefore(parsedHTML,this.elm.firstChild);
}
}
}
ECOTree.prototype.add = function (id, pid, dsc, w, h, c, bc, target, meta) {
var nw = w || this.config.defaultNodeWidth; //Width, height, colors, target and metadata defaults...
var nh = h || this.config.defaultNodeHeight;
var color = c || this.config.nodeColor;
var border = bc || this.config.nodeBorderColor;
var tg = (this.config.useTarget) ? ((typeof target == "undefined") ? (this.config.defaultTarget) : target) : null;
var metadata = (typeof meta != "undefined") ? meta : "";
var pnode = null; //Search for parent node in database
if (pid == -1) {
pnode = this.root;
} else {
for (var k = 0; k < this.nDatabaseNodes.length; k++) {
if (this.nDatabaseNodes[k].id == pid) {
pnode = this.nDatabaseNodes[k];
break;
}
}
}
var node = new ECONode(id, pid, dsc, nw, nh, color, border, tg, metadata); //New node creation...
node.nodeParent = pnode; //Set it's parent
pnode.canCollapse = true; //It's obvious that now the parent can collapse
var i = this.nDatabaseNodes.length; //Save it in database
node.dbIndex = this.mapIDs[id] = i;
this.nDatabaseNodes[i] = node;
var h = pnode.nodeChildren.length; //Add it as child of it's parent
node.siblingIndex = h;
pnode.nodeChildren[h] = node;
}
ECOTree.prototype.searchNodes = function (str) {
var node = null;
var m = this.config.searchMode;
var sm = (this.config.selectMode == ECOTree.SL_SINGLE);
if (typeof str == "undefined") return;
if (str == "") return;
var found = false;
var n = (sm) ? this.iLastSearch : 0;
if (n == this.nDatabaseNodes.length) n = this.iLastSeach = 0;
str = str.toLocaleUpperCase();
for (; n < this.nDatabaseNodes.length; n++)
{
node = this.nDatabaseNodes[n];
if (node.dsc.toLocaleUpperCase().indexOf(str) != -1 && ((m == ECOTree.SM_DSC) || (m == ECOTree.SM_BOTH))) {
node._setAncestorsExpanded();
this._selectNodeInt(node.dbIndex, false);
found = true;
}
if (node.meta.toLocaleUpperCase().indexOf(str) != -1 && ((m == ECOTree.SM_META) || (m == ECOTree.SM_BOTH))) {
node._setAncestorsExpanded();
this._selectNodeInt(node.dbIndex, false);
found = true;
}
if (sm && found) {
this.iLastSearch = n + 1;
break;
}
}
this.UpdateTree();
}
ECOTree.prototype.selectAll = function () {
if (this.config.selectMode != ECOTree.SL_MULTIPLE) return;
this._selectAllInt(true);
}
ECOTree.prototype.unselectAll = function () {
this._selectAllInt(false);
}
ECOTree.prototype.collapseAll = function () {
this._collapseAllInt(true);
}
ECOTree.prototype.expandAll = function () {
this._collapseAllInt(false);
}
/*增加了一个调用iframe.window函数*/
ECOTree.prototype.collapseNode = function (nodeid, upd) {
//alert(nodeid+', '+upd);
//ifDoc.getElementById("sample1").style.background="red";
ifWin.t.collapseNode(nodeid, upd);
var dbindex = this.mapIDs[nodeid];
this.nDatabaseNodes[dbindex].isCollapsed = !this.nDatabaseNodes[dbindex].isCollapsed;
if (upd) this.UpdateTree();
}
ECOTree.prototype.selectNode = function (nodeid, upd) {
this._selectNodeInt(this.mapIDs[nodeid], true);
if (upd) this.UpdateTree();
}
ECOTree.prototype.setNodeTitle = function (nodeid, title, upd) {
var dbindex = this.mapIDs[nodeid];
this.nDatabaseNodes[dbindex].dsc = title;
if (upd) this.UpdateTree();
}
ECOTree.prototype.setNodeMetadata = function (nodeid, meta, upd) {
var dbindex = this.mapIDs[nodeid];
this.nDatabaseNodes[dbindex].meta = meta;
if (upd) this.UpdateTree();
}
ECOTree.prototype.setNodeTarget = function (nodeid, target, upd) {
var dbindex = this.mapIDs[nodeid];
this.nDatabaseNodes[dbindex].target = target;
if (upd) this.UpdateTree();
}
ECOTree.prototype.setNodeColors = function (nodeid, color, border, upd) {
var dbindex = this.mapIDs[nodeid];
if (color) this.nDatabaseNodes[dbindex].c = color;
if (border) this.nDatabaseNodes[dbindex].bc = border;
if (upd) this.UpdateTree();
}
ECOTree.prototype.getSelectedNodes = function () {
var node = null;
var selection = [];
var selnode = null;
for (var n=0; n<this.nDatabaseNodes.length; n++) {
node = this.nDatabaseNodes[n];
if (node.isSelected)
{
selnode = {
"id" : node.id,
"dsc" : node.dsc,
"meta" : node.meta
}
selection[selection.length] = selnode;
}
}
return selection;
}
缩略图效果HTML
公司网络封锁文件外传,所以不能截图上来。请自行运行查看效果。