|
// TRICK to get all elements by class name
|
|
document.getElementsByClassName = function(cl) {
|
|
var retnode = [];
|
|
var myclass = new RegExp('\\b'+cl+'\\b');
|
|
var elem = this.getElementsByTagName('*');
|
|
for (var i = 0; i < elem.length; i++) {
|
|
var classes = elem[i].className;
|
|
if (myclass.test(classes))
|
|
retnode.push(elem[i]);
|
|
}
|
|
return retnode;
|
|
};
|
|
|
|
// There are 3 kinds of cell
|
|
var CELL_TYPE_ORGANIZATION = 0;
|
|
var CELL_TYPE_CATEGORY = 1;
|
|
var CELL_TYPE_PERSON = 2;
|
|
|
|
// Cell orientations
|
|
var ORIENTATION_HORIZONTAL = 0;
|
|
var ORIENTATION_VERTICAL = 1;
|
|
var ORIENTATION_RIGHT = 2;
|
|
var ORIENTATION_LEFT = 3;
|
|
|
|
var cellRightNumber = -1;
|
|
var cellRightOrigin = -1;
|
|
var cellLeftNumber = -1;
|
|
var cellLeftOrigin = -1;
|
|
|
|
var V_MARGIN = 20;
|
|
var H_MARGIN = 20;
|
|
var H_GAP = 50;
|
|
var V_GAP = 40; // was 60
|
|
var V_GAP_SIDEBOX = 300;
|
|
var H_GAP_SIDEBOX = V_GAP / 2;
|
|
var MAIN_DIV_BORDER_WIDTH = 3;
|
|
var START_OPACITY_STEP = 0;
|
|
var CELLSIZE = 180;
|
|
|
|
var mainDiv;
|
|
var cellsCount;
|
|
var maxLevel = 0;
|
|
|
|
var invisibleDiv;
|
|
|
|
var detailDiv;
|
|
var detailTable;
|
|
var detailCell;
|
|
|
|
var currentId = -1;
|
|
var currentX;
|
|
var currentY;
|
|
var focusOnDetailDiv = false;
|
|
|
|
//function JCell(id, name, infoSup, url, level, type, cellType, linkCenter, linkDetails, upperLink)
|
|
function JCell(options)
|
|
{
|
|
// parameters
|
|
// ----------
|
|
this.id = options['id']; // id - use for links between cells
|
|
this.title = options['title']; // cell title
|
|
this.roles = options['roles']; // array of roles (only for organizations)
|
|
this.userAttributes = options['userAttributes']; // array of attributes (only for persons)
|
|
this.detailsURL = options['detailsURL']; // URL to call when details link is clicked (only for organizations)
|
|
this.catMembers = options['catMembers']; // members of current category
|
|
this.level = options['level']; // level for css
|
|
this.cellType = options['cellType']; // 0 = unit or 1 = category, personn
|
|
this.showCenterLink = options['showCenterLink']; // 1 if center link must be visible, 0 otherwise
|
|
this.linkDetails = options['showDetailsLink']; // 1 if details link must be visible, 0 otherwise
|
|
this.onClickURL = options['onClickURL']; // URL to call when title link is clicked
|
|
this.commonUserURL = options['commonUserURL']; // URL to call when a user is clicked
|
|
this.parentURL = options['parentURL']; // URL to call when parent link is clicked
|
|
this.className = options['className']; // CSS class name
|
|
this.extraClassName = options['extraClassName']; // Specific CSS class name
|
|
this.usersIcon = options['usersIcon']; // icon to display details Link
|
|
this.innerUsers = options['innerUsers']; // users to display inside the same cell
|
|
|
|
// calculated variables
|
|
// --------------------
|
|
this.gaps = new Array();
|
|
this.div = null;
|
|
|
|
// horizontal -> left right
|
|
this.leftCell = null;
|
|
this.rightCell = null;
|
|
|
|
// vertical -> top down
|
|
this.topCell = null;
|
|
this.downCell = null;
|
|
|
|
this.upLinks = new Array();
|
|
this.downLinks = new Array();
|
|
this.startX = -1;
|
|
this.endX = -1;
|
|
this.startY = -1;
|
|
this.endY = -1;
|
|
this.downLinksAlreadyDone = 0;
|
|
}
|
|
|
|
|
|
function JLink(origin, destination, type, orientation)
|
|
{
|
|
this.origin = origin;
|
|
this.destination = destination;
|
|
this.type = type;
|
|
this.orientation = orientation;
|
|
|
|
if(orientation == ORIENTATION_RIGHT) {
|
|
cellRightNumber = destination;
|
|
cellRightOrigin = origin;
|
|
}
|
|
else if(orientation == ORIENTATION_LEFT) {
|
|
cellLeftNumber = destination;
|
|
cellLeftOrigin = origin;
|
|
}
|
|
}
|
|
|
|
function chartinit()
|
|
{
|
|
START_OPACITY_STEP = 15;
|
|
|
|
mainDiv = document.getElementById("chart");
|
|
cellsCount = jCells.length;
|
|
var i;
|
|
for (i = 0; i < cellsCount; i++)
|
|
{
|
|
maxLevel = Math.max(maxLevel, jCells[i].level);
|
|
}
|
|
maxLevel++;
|
|
|
|
buildCellDIVs();
|
|
buildUpAndDownLinks();
|
|
whenSilverpeasEntirelyLoaded().then(function() {
|
|
placeCells();
|
|
buildLinks();
|
|
|
|
|
|
var maxWidth = 0;
|
|
var maxHeight = 0;
|
|
// supprime le px
|
|
for (i = 0; i < jCells.length; i++)
|
|
{
|
|
var div = jCells[i].div;
|
|
maxWidth = Math.max(maxWidth, div.offsetLeft + div.offsetWidth + 2);
|
|
var height = parseInt(div.style.top.substring(0, div.style.top.indexOf('px'))) + div.offsetHeight;
|
|
maxHeight = (maxHeight > height) ? maxHeight : height;
|
|
}
|
|
|
|
// on centre le scroll sur la case 0 (moitié de la largeur max moins un
|
|
// demi écran moins une demi cellule)
|
|
window.scroll( parseInt( maxWidth / 2 - screen.width / 2 + CELLSIZE / 2), 0);
|
|
mainDiv.style.height = maxHeight + "px";
|
|
|
|
centerBoxesAndLinks();
|
|
|
|
activateUserZoom();
|
|
});
|
|
}
|
|
|
|
function centerBoxesAndLinks() {
|
|
var offsetX = mainDiv.offsetLeft + H_MARGIN;
|
|
var offsetY = mainDiv.offsetTop + V_MARGIN;
|
|
|
|
for (var i = 0; i < jCells.length; i++)
|
|
{
|
|
var div = jCells[i].div;
|
|
div.style.marginLeft = offsetX + "px";
|
|
div.style.marginTop = offsetY + "px";
|
|
}
|
|
|
|
for (i=0; i<3; i++) {
|
|
var linklements = document.getElementsByClassName('link'+i);
|
|
for (var j = 0; j < linklements.length; j++)
|
|
{
|
|
linklements[j].style.marginLeft = offsetX + "px";
|
|
linklements[j].style.marginTop = offsetY + "px";
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Build cells as HTML DIVs
|
|
*/
|
|
function buildCellDIVs()
|
|
{
|
|
var i;
|
|
for (i = 0; i < cellsCount; i++)
|
|
{
|
|
buildCellDIV(jCells[i]);
|
|
}
|
|
}
|
|
|
|
function buildCellDIV(jCell)
|
|
{
|
|
var firstInnerDiv = null;
|
|
|
|
// Main DIV
|
|
var div = document.createElement("DIV");
|
|
var uniqueId = decodeURIComponent(StringUtil.defaultStringIfNotDefined(jCell.detailsURL)).replace('Main?baseOu=', '').replace(/[^a-z0-9]/ig, '_');
|
|
if (uniqueId) {
|
|
div.id += 'uniqueId_' + uniqueId;
|
|
}
|
|
div.className = "cell"+jCell.className+" "+jCell.extraClassName;
|
|
|
|
// DIV Content as a HTML table
|
|
var table = document.createElement("TABLE");
|
|
|
|
// back link
|
|
if (jCell.parentURL) {
|
|
var backRow = table.insertRow(-1);
|
|
var backCell = backRow.insertCell(-1);
|
|
backCell.className = "cellInfos";
|
|
backCell.colSpan = 2;
|
|
backCell.align = "right";
|
|
backCell.innerHTML = "<a href=\"" + jCell.parentURL + "\" class=\"gotoParent\"> </a>";
|
|
}
|
|
|
|
// Title
|
|
var titleRow = table.insertRow(-1);
|
|
var titleCell = titleRow.insertCell(-1);
|
|
titleCell.className = "cellName";
|
|
titleCell.colSpan = 2;
|
|
titleCell.innerHTML = getTitle(jCell);
|
|
|
|
switch(jCell.cellType)
|
|
{
|
|
// for organizations, list roles
|
|
case CELL_TYPE_ORGANIZATION:
|
|
|
|
// DIV Content as a HTML table
|
|
for (var j = 0; j < jCell.userAttributes.length; j++) {
|
|
var unitAttribute = jCell.userAttributes[j]['value'];
|
|
if (unitAttribute.length > 0) {
|
|
var attributeRow = table.insertRow(-1);
|
|
var attributeCell = attributeRow.insertCell(-1);
|
|
attributeCell.className = "cellUnitAttribute";
|
|
attributeCell.colSpan = 2;
|
|
attributeCell.align = "center";
|
|
attributeCell.innerHTML = jCell.userAttributes[j]['label'] + " : " + unitAttribute;
|
|
}
|
|
}
|
|
|
|
// Roles
|
|
for (var i = 0; i < jCell.roles.length; i++) {
|
|
var user = jCell.roles[i]['userFullName'];
|
|
if (user.length > 0) {
|
|
var roleRow = table.insertRow(-1);
|
|
var roleCell = roleRow.insertCell(-1);
|
|
roleCell.className = "cellInfos";
|
|
roleCell.colSpan = 2;
|
|
roleCell.align = "center";
|
|
var avatar = getAvatar(jCell.roles[i]);
|
|
roleCell.innerHTML = "<span class=\"role\">"+jCell.roles[i]['role'] + " : </span>" + avatar + user;
|
|
}
|
|
}
|
|
|
|
// Links
|
|
var linksRow = table.insertRow(-1);
|
|
|
|
var spacer = linksRow.insertCell(-1);
|
|
spacer.className = "cellLinkLeft";
|
|
spacer.innerHTML = " ";
|
|
|
|
var detailLinkCell = linksRow.insertCell(-1);
|
|
detailLinkCell.className = "cellLinkRight";
|
|
if (jCell.linkDetails) {
|
|
if (jCell.usersIcon != '') {
|
|
detailLinkCell.innerHTML = "<a href=\"" + jCell.detailsURL +"&chartType=1\"><img src='"+jCell.usersIcon+"' border='0'/></a>"
|
|
} else {
|
|
detailLinkCell.innerHTML = "<a href=\"" + jCell.detailsURL +"&chartType=1\">Détails</a>"
|
|
}
|
|
} else {
|
|
detailLinkCell.innerHTML = " "
|
|
}
|
|
break;
|
|
|
|
case CELL_TYPE_CATEGORY:
|
|
if (jCell.catMembers) {
|
|
for (i = 0; i < jCell.catMembers.length; i++) {
|
|
var memberRow = table.insertRow(-1);
|
|
var memberCell = memberRow.insertCell(-1);
|
|
memberCell.className = "cellInfos";
|
|
memberCell.colSpan = 2;
|
|
memberCell.align = "center";
|
|
avatar = getAvatar(jCell.catMembers[i]);
|
|
memberCell.innerHTML = "<a target=\"_blank\" href=\"" + jCell.commonUserURL + jCell.catMembers[i]['login'] + "\">" + avatar + jCell.catMembers[i]['userFullName'] + "</a>";
|
|
}
|
|
}
|
|
|
|
if (jCell.innerUsers) {
|
|
for (i = 0; i < jCell.innerUsers.length; i++) {
|
|
var divMembers = document.createElement("DIV");
|
|
divMembers.className = "innerUser";
|
|
avatar = getAvatar(jCell.innerUsers[i]);
|
|
divMembers.innerHTML = "<a target=\"_blank\" href=\"" + jCell.commonUserURL + jCell.innerUsers[i]['login'] + "\">" + avatar + jCell.innerUsers[i]['userFullName'] + "</a>";
|
|
div.appendChild(divMembers);
|
|
|
|
// DIV Content as a HTML table
|
|
var tableMembers = document.createElement("TABLE");
|
|
for (j = 0; j < jCell.innerUsers[i]['userAttributes'].length; j++) {
|
|
var userAttribute = jCell.innerUsers[i]['userAttributes'][j]['value'];
|
|
if (userAttribute.length > 0) {
|
|
var userAttributeRow = tableMembers.insertRow(-1);
|
|
var userAttributeCell = userAttributeRow.insertCell(-1);
|
|
userAttributeCell.className = "celluserAttribute";
|
|
userAttributeCell.colSpan = 2;
|
|
userAttributeCell.align = "center";
|
|
userAttributeCell.innerHTML = "<span class=\"attribute\">"+jCell.innerUsers[i]['userAttributes'][j]['label'] + " : </span>" + userAttribute;
|
|
}
|
|
}
|
|
divMembers.appendChild(tableMembers);
|
|
|
|
if (i==0) {
|
|
firstInnerDiv = divMembers;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CELL_TYPE_PERSON:
|
|
default:
|
|
// User Attributes
|
|
if (jCell.userAttributes) {
|
|
for (i = 0; i < jCell.userAttributes.length; i++) {
|
|
userAttribute = jCell.userAttributes[i]['value'];
|
|
if (userAttribute.length > 0) {
|
|
userAttributeRow = table.insertRow(-1);
|
|
userAttributeCell = userAttributeRow.insertCell(-1);
|
|
userAttributeCell.className = "celluserAttribute";
|
|
userAttributeCell.colSpan = 2;
|
|
userAttributeCell.align = "center";
|
|
userAttributeCell.innerHTML = jCell.userAttributes[i]['label'] + " : " + userAttribute;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (firstInnerDiv) {
|
|
div.insertBefore(table, firstInnerDiv);
|
|
}
|
|
else {
|
|
div.appendChild(table);
|
|
}
|
|
mainDiv.appendChild(div);
|
|
|
|
div.style.width = CELLSIZE + "px"; // table.offsetWidth + 10; on fixe pour eviter les pbs
|
|
jCell.div = div;
|
|
}
|
|
|
|
function getAvatar(user) {
|
|
var avatar = "";
|
|
if (user['avatar'].length > 0) {
|
|
avatar = "<img src=\""+webContext+user['avatar']+"\" class=\"avatar\" alt=\"\"/>";
|
|
}
|
|
return avatar;
|
|
}
|
|
|
|
/**
|
|
* Get CSS class name for given cell type.
|
|
*
|
|
* @param cellType cell type (CELL_TYPE_ORGANIZATION, CELL_TYPE_CATEGORY, CELL_TYPE_PERSON)
|
|
*
|
|
* @returns CSS class name
|
|
*/
|
|
function getCellClassName(cellType) {
|
|
var className = null;
|
|
switch(cellType)
|
|
{
|
|
case CELL_TYPE_ORGANIZATION:
|
|
className = "cellOrganization";
|
|
break;
|
|
|
|
case CELL_TYPE_CATEGORY:
|
|
className = "cellCategory";
|
|
break;
|
|
|
|
case CELL_TYPE_PERSON:
|
|
default:
|
|
className = "cellPerson";
|
|
break;
|
|
}
|
|
|
|
return className;
|
|
}
|
|
|
|
/**
|
|
* Get HTML code for given cell's title.
|
|
*
|
|
* @param cellType cell type (CELL_TYPE_ORGANIZATION, CELL_TYPE_CATEGORY, CELL_TYPE_PERSON)
|
|
*
|
|
* @returns HTML Code
|
|
*/
|
|
|
|
function getTitle(jCell) {
|
|
var htmlCode = null;
|
|
|
|
switch(jCell.cellType)
|
|
{
|
|
case CELL_TYPE_ORGANIZATION:
|
|
if(jCell.showCenterLink){
|
|
htmlCode = "<a href=\"" + jCell.onClickURL +"&chartType=0\">"+jCell.title+"</a>";
|
|
}
|
|
else {
|
|
htmlCode = jCell.title;
|
|
}
|
|
break;
|
|
|
|
case CELL_TYPE_PERSON:
|
|
htmlCode = "<a target=\"_blank\" href=\"" + jCell.onClickURL+ "\">" + jCell.title + "</a>";
|
|
break;
|
|
|
|
case CELL_TYPE_CATEGORY:
|
|
default:
|
|
htmlCode = jCell.title;
|
|
break;
|
|
}
|
|
|
|
return htmlCode;
|
|
}
|
|
|
|
/**
|
|
* Build links between cells
|
|
*/
|
|
function buildUpAndDownLinks() {
|
|
if(jLinks.length > 0){
|
|
var jLink;
|
|
var jCell1;
|
|
var jCell2;
|
|
for (var i = 0; i < jLinks.length; i++)
|
|
{
|
|
jLink = jLinks[i];
|
|
if ( (jLink.orientation != ORIENTATION_LEFT) && (jLink.orientation != ORIENTATION_RIGHT) ) {
|
|
jCell1 = getJCell(jLink.origin);
|
|
jCell2 = getJCell(jLink.destination);
|
|
if (jCell1.level < jCell2.level)
|
|
{
|
|
jCell1.downLinks[jCell1.downLinks.length] = jLink;
|
|
jCell2.upLinks[jCell2.upLinks.length] = jLink;
|
|
}
|
|
else if (jCell1.level > jCell2.level)
|
|
{
|
|
jCell1.upLinks[jCell1.upLinks.length] = jLink;
|
|
jCell2.downLinks[jCell2.downLinks.length] = jLink;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function placeCells()
|
|
{
|
|
var i;
|
|
var j;
|
|
var topGap = mainDiv.offsetTop + V_MARGIN;
|
|
var leftGap;
|
|
var jCell;
|
|
var div;
|
|
var jLevels = new Array(maxLevel);
|
|
|
|
// on classe par niveau (vertical seulement)
|
|
for (i = 0; i < maxLevel; i++)
|
|
{
|
|
jLevels[i] = new Array();
|
|
|
|
for (j = 0; j < cellsCount; j++)
|
|
{
|
|
if (jCells[j].level == i)
|
|
{
|
|
jLevels[i][jLevels[i].length] = jCells[j];
|
|
}
|
|
}
|
|
|
|
leftGap = mainDiv.offsetLeft;
|
|
for (j = 0; j < jLevels[i].length; j++)
|
|
{
|
|
if (j > 0)
|
|
{
|
|
jLevels[i][j].leftCell = jLevels[i][j - 1];
|
|
}
|
|
if (j < (jLevels[i].length - 1))
|
|
{
|
|
jLevels[i][j].rightCell = jLevels[i][j + 1];
|
|
}
|
|
|
|
div = jLevels[i][j].div;
|
|
if ( (jLevels[i][j].className==3) || (jLevels[i][j].className==4) ) {
|
|
var x = topGap - H_GAP_SIDEBOX;
|
|
div.style.top = x + "px";
|
|
} else {
|
|
div.style.top = topGap + "px";
|
|
}
|
|
|
|
div.style.left = leftGap + "px";
|
|
}
|
|
|
|
topGap += V_GAP + (div != null ? div.offsetHeight : 0);
|
|
}
|
|
|
|
//resizeBoxes(jLevels);
|
|
|
|
moveHorizontalAndVertical(jLevels);
|
|
var x = topGap + V_MARGIN * 3;
|
|
mainDiv.style.height = x + "px";
|
|
|
|
var lastLevel = jLevels[jLevels.length-1];
|
|
var chartWidth = lastLevel[lastLevel.length-1].div.offsetLeft + lastLevel[lastLevel.length-1].div.offsetWidth - lastLevel[0].div.offsetLeft;
|
|
x = chartWidth + (H_MARGIN*2);
|
|
mainDiv.style.width = x + "px";
|
|
|
|
moveMain(jLevels);
|
|
var maxLevelWidth = 0;
|
|
for (i = 0; i < jLevels.length; i++)
|
|
{
|
|
div = jLevels[i][jLevels[i].length - 1].div;
|
|
maxLevelWidth = Math.max(maxLevelWidth, div.offsetLeft + div.offsetWidth + 2);
|
|
}
|
|
if (maxLevelWidth < mainDiv.offsetWidth)
|
|
{
|
|
var marginWidth = parseInt((mainDiv.offsetWidth - maxLevelWidth) / 2);
|
|
for (i = 0; i < cellsCount; i++)
|
|
{
|
|
x = jCells[i].div.offsetLeft + marginWidth
|
|
jCells[i].div.style.left = x + "px";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var maxCount = 0; // nombre de cellules max. par ligne
|
|
for (i = 0; i < jLevels.length; i++)
|
|
{
|
|
maxCount = Math.max(maxCount, jLevels[i].length);
|
|
}
|
|
maxCount--;
|
|
var gap = parseInt((maxLevelWidth - mainDiv.offsetWidth) / maxCount) + 5;
|
|
H_GAP = Math.max(H_GAP - gap, 5);
|
|
for (i = 0; i < jLevels.length; i++)
|
|
{
|
|
leftGap = H_GAP;
|
|
for (j = 0; j < jLevels[i].length; j++)
|
|
{
|
|
jCell = jLevels[i][j];
|
|
if (jCell.upLinks.length == 1)
|
|
{
|
|
if(jCell.upLinks[0].orientation == ORIENTATION_VERTICAL)
|
|
{
|
|
// case orientation vertical du niveau
|
|
// on ne peut pas être recursif
|
|
// on recup la case du dessus
|
|
var currentOrigin = jCell.upLinks[0].origin;
|
|
var jcellorigin = getJCell(currentOrigin);
|
|
div = jLevels[i][j].div;
|
|
div.style.left = jcellorigin.div.offsetLeft + "px";
|
|
}else
|
|
{
|
|
div = jLevels[i][j].div;
|
|
leftGap = parseInt(div.style.left) + H_GAP;
|
|
div.style.left = leftGap + "px";
|
|
}
|
|
}else
|
|
{
|
|
// case 0 -> no up link
|
|
div = jLevels[i][j].div;
|
|
div.style.left = leftGap + "px";
|
|
leftGap += div.offsetWidth + H_GAP;
|
|
}
|
|
}
|
|
}
|
|
moveMain(jLevels);
|
|
}
|
|
|
|
// on refait une passe si on a cellule droite ou gauche
|
|
// il faut que la case supérieur (case 0) soit bien placé
|
|
for (i = 0; i < jLevels.length; i++)
|
|
{
|
|
for (j = 0; j < jLevels[i].length; j++)
|
|
{
|
|
if(cellRightNumber != -1 && cellRightNumber == jLevels[i][j].id){
|
|
// la cellule est une cellule droite
|
|
div = jLevels[i][j].div;
|
|
var divOrigin = jCells[cellRightOrigin].div;
|
|
// suppr le px
|
|
var originLeft = divOrigin.style.left;
|
|
var origin = originLeft.substring(0,originLeft.length - 2);
|
|
var intOrigin = parseInt(origin);
|
|
x = intOrigin + CELLSIZE;
|
|
div.style.left = x + "px"; // on décalle d'une
|
|
// cellule si c'est
|
|
// possible
|
|
}else if(cellLeftNumber != -1 && cellLeftNumber == jLevels[i][j].id){
|
|
// la cellule est une cellule gauche
|
|
div = jLevels[i][j].div;
|
|
divOrigin = jCells[cellLeftOrigin].div;
|
|
// suppr le px
|
|
originLeft = divOrigin.style.left;
|
|
origin = originLeft.substring(0,originLeft.length - 2);
|
|
intOrigin = parseInt(origin);
|
|
if(intOrigin > CELLSIZE){
|
|
x = intOrigin - CELLSIZE;
|
|
div.style.left = x + "px"; // on décalle d'une
|
|
// cellule si c'est
|
|
// possible
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function moveMain(jLevels)
|
|
{
|
|
for (var i = 0; i < jLevels.length; i++)
|
|
{
|
|
moveMain1(jLevels[i]);
|
|
}
|
|
for (i = (jLevels.length - 1); i >= 0; i--)
|
|
{
|
|
moveMain1(jLevels[i]);
|
|
}
|
|
for (i = 0; i < jLevels.length; i++)
|
|
{
|
|
moveMain2(jLevels[i]);
|
|
}
|
|
for (i = (jLevels.length - 1); i >= 0; i--)
|
|
{
|
|
moveMain2(jLevels[i]);
|
|
}
|
|
}
|
|
|
|
function moveMain1(jLevels)
|
|
{
|
|
var jCell;
|
|
var jCell0;
|
|
var jCell1;
|
|
var x0;
|
|
var x1;
|
|
var i;
|
|
for (i = 0; i < jLevels.length; i++)
|
|
{
|
|
jCell0 = jLevels[i];
|
|
if (jCell0.downLinks.length == 1)
|
|
{
|
|
x0 = getMiddleX(jCell0);
|
|
jCell1 = getJCell(jCell0.downLinks[0].destination);
|
|
x1 = getMiddleX(jCell1);
|
|
if (x0 != x1)
|
|
{
|
|
jCell = (x0 > x1 ? jCell1 : jCell0);
|
|
moveRight(jCell, Math.abs(x0 - x1));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function moveMain2(jLevels)
|
|
{
|
|
var jCell0;
|
|
var jCell1;
|
|
var jCell2;
|
|
var x0;
|
|
var x1;
|
|
var i;
|
|
for (i = 0; i < jLevels.length; i++)
|
|
{
|
|
jCell0 = jLevels[i];
|
|
if (jCell0.downLinks.length > 1)
|
|
{
|
|
x0 = getMiddleX(jCell0);
|
|
jCell1 = getJCell(jCell0.downLinks[0].destination);
|
|
jCell2 = getJCell(jCell0.downLinks[jCell0.downLinks.length - 1].destination);
|
|
x1 = parseInt((getMiddleX(jCell1) + getMiddleX(jCell2)) / 2);
|
|
if (x0 != x1)
|
|
{
|
|
var jCell = (x0 > x1 ? jCell1 : jCell0);
|
|
moveRight(jCell, Math.abs(x0 - x1));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function getMiddleX(jCell)
|
|
{
|
|
return parseInt(jCell.div.offsetLeft + jCell.div.offsetWidth / 2);
|
|
}
|
|
|
|
function moveRight(jCell, gap)
|
|
{
|
|
var div = jCell.div;
|
|
var x = div.offsetLeft + gap;
|
|
div.style.left = x + "px";
|
|
jCell = jCell.rightCell;
|
|
while (jCell != null)
|
|
{
|
|
div = jCell.div;
|
|
x = div.offsetLeft + gap;
|
|
div.style.left = x + "px";
|
|
jCell = jCell.rightCell;
|
|
}
|
|
}
|
|
|
|
function getJCell(id)
|
|
{
|
|
var i;
|
|
for (i = 0; i < cellsCount; i++)
|
|
{
|
|
if (jCells[i].id == id)
|
|
{
|
|
return jCells[i];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function resizeBoxes(jLevels)
|
|
{
|
|
// recuperation max
|
|
var maxWidth = new Array(jLevels.length);
|
|
var maxHeight = new Array(jLevels.length);
|
|
for (var i = 0; i < jLevels.length; i++)
|
|
{
|
|
for (var j = 0; j < jLevels[i].length; j++)
|
|
{
|
|
var div = jLevels[i][j].div;
|
|
//largeur max
|
|
if(div.style.width > maxWidth)
|
|
{
|
|
maxWidth[i] = div.offsetWidth;
|
|
}
|
|
// hauteur max
|
|
if(div.style.height > maxHeight)
|
|
{
|
|
maxHeight[i] = div.offsetHeight;
|
|
}
|
|
}
|
|
}
|
|
// resize all boxes
|
|
for (i = 0; i < jLevels.length; i++)
|
|
{
|
|
for (j = 0; j < jLevels[i].length; j++)
|
|
{
|
|
div = jLevels[i][j].div;
|
|
div.style.width = maxWidth[i] + "px";
|
|
div.style.height = maxHeight[i] + "px";
|
|
}
|
|
}
|
|
}
|
|
|
|
function moveHorizontalAndVertical(jLevels)
|
|
{
|
|
var jCell;
|
|
var leftGap;
|
|
var V_GAP_SAME_LEVEL = 20;
|
|
var H_GAP = 50;
|
|
|
|
for (var i = 0; i < jLevels.length; i++)
|
|
{
|
|
var topGap = -1;
|
|
leftGap = 0;
|
|
|
|
var maximumHeight = calculateMaximumHeight(jLevels[i]);
|
|
|
|
for (var j = 0; j < jLevels[i].length; j++)
|
|
{
|
|
jCell = jLevels[i][j];
|
|
jLevels[i][j].gaps["y"]=0;
|
|
jLevels[i][j].gaps["x"]=0;
|
|
if (jCell.upLinks.length == 1)
|
|
{
|
|
var currentOrigin = jCell.upLinks[0].origin;
|
|
if(jCell.upLinks[0].orientation == ORIENTATION_HORIZONTAL) // same link on one level
|
|
{
|
|
// oriention horizontal uniquement
|
|
var div = jCell.div;
|
|
|
|
if (jLevels[0][0].parentURL) {
|
|
if(j%2==0 || jCell.cellType!=CELL_TYPE_ORGANIZATION){
|
|
if(j>0){
|
|
if (jCell.cellType==CELL_TYPE_ORGANIZATION) {
|
|
jLevels[i][j].gaps["x"] = -1*parseInt(jLevels[i][j-1].div.style.width) / 2.5;
|
|
}
|
|
else {
|
|
jLevels[i][j].gaps["x"] = H_MARGIN*4;
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
jLevels[i][j].gaps["y"]=maximumHeight;
|
|
jLevels[i][j].gaps["x"] = -1*parseInt(jLevels[i][j-1].div.style.width) / 2.5;
|
|
var x = parseInt(div.style.top) + maximumHeight + H_MARGIN;
|
|
div.style.top= x + "px";
|
|
}
|
|
var xx = leftGap + jCell.gaps["x"];
|
|
|
|
} else {
|
|
if(j>0){
|
|
if (jCell.cellType==CELL_TYPE_ORGANIZATION) {
|
|
jLevels[i][j].gaps["x"] = -1*parseInt(jLevels[i][j-1].div.style.width) / 1000;
|
|
}
|
|
else {
|
|
jLevels[i][j].gaps["x"] = H_MARGIN*4;
|
|
}
|
|
}
|
|
var xx = leftGap + jCell.gaps["x"] + (j*10);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
div.style.left = xx + "px";
|
|
leftGap = leftGap + div.offsetWidth + jCell.gaps["x"];
|
|
|
|
}else if(jCell.upLinks[0].orientation == ORIENTATION_RIGHT || jCell.upLinks[0].orientation == ORIENTATION_LEFT)
|
|
{
|
|
// oriention droite -> horizontal
|
|
div = jCell.div;
|
|
div.style.top = H_GAP_SIDEBOX + "px";
|
|
leftGap += div.offsetWidth + H_GAP;
|
|
} else
|
|
{
|
|
// orientation vertical uniquement
|
|
div = jCell.div;
|
|
var jcellorigin = getJCell(currentOrigin);
|
|
leftGap = jcellorigin.div.offsetLeft;
|
|
topGap = jcellorigin.div.offsetTop + jcellorigin.div.offsetHeight + V_GAP_SAME_LEVEL + jcellorigin.downLinksAlreadyDone;
|
|
jcellorigin.downLinksAlreadyDone += jCell.div.offsetHeight + V_GAP_SAME_LEVEL;
|
|
div.style.top = topGap + "px";
|
|
div.style.left = leftGap + "px";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function calculateMaximumHeight(jLevel)
|
|
{
|
|
var maximumHeight=0;
|
|
for (var j = 0; j < jLevel.length; j++)
|
|
{
|
|
var jCell = jLevel[j];
|
|
if(jCell.div.clientHeight > maximumHeight)
|
|
{
|
|
maximumHeight=jCell.div.clientHeight;
|
|
}
|
|
}
|
|
return maximumHeight;
|
|
}
|
|
|
|
function buildLinks()
|
|
{
|
|
var X_DEC = 10;
|
|
|
|
var i;
|
|
var jLink;
|
|
var jCell0;
|
|
var div0;
|
|
var x0;
|
|
var y0;
|
|
var div1;
|
|
var jCell1;
|
|
var x1;
|
|
var y1;
|
|
var jCellTmp;
|
|
var xDiff;
|
|
for (i = 0; i < jLinks.length; i++)
|
|
{
|
|
jLink = jLinks[i];
|
|
jCell0 = getJCell(jLink.origin);
|
|
jCell1 = getJCell(jLink.destination);
|
|
if (jCell0 != null && jCell1 != null)
|
|
{
|
|
if (jCell0.level != jCell1.level)
|
|
{
|
|
if (jCell0.level > jCell1.level)
|
|
{
|
|
jCellTmp = jCell1;
|
|
jCell1 = jCell0;
|
|
jCell0 = jCellTmp;
|
|
}
|
|
if(jLink.orientation == ORIENTATION_HORIZONTAL)
|
|
{
|
|
div0 = jCell0.div;
|
|
x0 = parseInt(div0.offsetLeft + div0.offsetWidth / 2);
|
|
y0 = div0.offsetTop + div0.offsetHeight - 2;
|
|
div1 = jCell1.div;
|
|
x1 = parseInt(div1.offsetLeft + div1.offsetWidth / 2);
|
|
y1 = div1.offsetTop + 2;
|
|
xDiff = Math.abs(x1 - x0);
|
|
if (xDiff == 0)
|
|
{
|
|
buildLink(jLink.type, x0, y0, 0, y1 - y0);
|
|
}
|
|
else if (xDiff < 20 && jCell0.downLinks.length < 2)
|
|
{
|
|
buildLink(jLink.type, Math.min(x0, x1) + parseInt(xDiff / 2), y0, 0, y1 - y0);
|
|
}
|
|
else
|
|
{
|
|
var part1y = 0;
|
|
if(jCell1.gaps["y"]>0)
|
|
{
|
|
part1y = parseInt((y1 - y0 - jCell1.gaps["y"]- H_MARGIN) * 5 / 6);
|
|
}
|
|
else
|
|
{
|
|
part1y = parseInt((y1 - y0) * 5 / 6);
|
|
}
|
|
|
|
var part2y = y1 - y0 - part1y;
|
|
|
|
buildLink(jLink.type, x0, y0, 0, part1y); // premier
|
|
// lien
|
|
// vertical
|
|
buildLink(jLink.type, x1, y0 + part1y, 0, part2y); // deuxième
|
|
// lien
|
|
// vertical
|
|
buildLink(jLink.type, Math.min(x0, x1), y0 + part1y, Math.abs(x1 - x0), 0); // lien
|
|
// horizontal
|
|
}
|
|
}
|
|
else if (jLink.orientation == ORIENTATION_VERTICAL)
|
|
{
|
|
// lien de type vertical
|
|
div0 = jCell0.div;
|
|
x0 = parseInt(div0.offsetLeft);
|
|
y0 = div0.offsetTop + div0.offsetHeight/2;
|
|
div1 = jCell1.div;
|
|
x1 = parseInt(div1.offsetLeft);
|
|
y1 = div1.offsetTop + div1.offsetHeight/2;
|
|
// ligne horizontale coté haut
|
|
buildLink(jLink.type, x0 - X_DEC, y0, X_DEC, 0);
|
|
// ligne droite verticals
|
|
buildLink(jLink.type, x0 - X_DEC, y0, 0, y1 - y0);
|
|
// ligne horizontale coté bas
|
|
buildLink(jLink.type, x1 - X_DEC, y1, X_DEC, 0);
|
|
}
|
|
else if (jLink.orientation == ORIENTATION_RIGHT)
|
|
{
|
|
// lien de type case à droite
|
|
div0 = jCell0.div;
|
|
x0 = parseInt(div0.offsetLeft + div0.offsetWidth / 2);
|
|
y0 = div0.offsetTop;
|
|
div1 = jCell1.div;
|
|
x1 = div1.offsetLeft;
|
|
y1 = parseInt(div1.offsetTop + div1.offsetHeight/2);
|
|
// ligne droite verticals
|
|
buildLink(jLink.type, x0, y0, 0, y1 - y0);
|
|
// ligne horizontale coté bas
|
|
buildLink(jLink.type, x0, y1, x1 - x0, 0);
|
|
}
|
|
else if (jLink.orientation == ORIENTATION_LEFT){
|
|
// lien de type case à gauche
|
|
div0 = jCell0.div;
|
|
x0 = parseInt(div0.offsetLeft + div0.offsetWidth / 2);
|
|
y0 = div0.offsetTop;
|
|
div1 = jCell1.div;
|
|
x1 = div1.offsetLeft;
|
|
y1 = div1.offsetTop + div1.offsetHeight/2;
|
|
// ligne droite verticale
|
|
buildLink(jLink.type, x0, y0, 0, y1 - y0);
|
|
// ligne horizontale coté bas
|
|
buildLink(jLink.type, x1, y1, x0 - x1, 0);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
div0 = jCell0.div;
|
|
div1 = jCell1.div;
|
|
if (div0.offsetLeft > div1.offsetLeft)
|
|
{
|
|
var div = div1;
|
|
div1 = div0;
|
|
div0 = div;
|
|
}
|
|
x0 = div0.offsetLeft + div0.offsetWidth;
|
|
y0 = div0.offsetTop + parseInt(div0.offsetHeight / 2);
|
|
x1 = div1.offsetLeft;
|
|
y1 = div1.offsetTop + parseInt(div0.offsetHeight / 2);
|
|
buildLink(jLink.type, x0, y0, x1 - x0, y1 - y0);
|
|
}
|
|
}
|
|
}
|
|
|
|
function buildLink(type, left, top, width, height)
|
|
{
|
|
// contruire une ligne de type "type" depuis (left, top) sur une longueur de
|
|
// (width, height)
|
|
var div = document.createElement("DIV");
|
|
div.className = "link" + type;
|
|
div.style.left = left + "px";
|
|
div.style.top = Math.floor(top) + "px";
|
|
div.style.width = width + "px";
|
|
div.style.height = height + "px";
|
|
if (height == 0)
|
|
{
|
|
// IE bug : fill the div with an empty span to keep 0 height.
|
|
div.innerHTML = "<span></span>";
|
|
}
|
|
mainDiv.appendChild(div);
|
|
}
|