/* * FusionCharts Free v2 * http://www.fusioncharts.com/free * * Copyright (c) 2009 InfoSoft Global (P) Ltd. * Dual licensed under the MIT (X11) and GNU GPL licenses. * http://www.fusioncharts.com/free/license * * MIT License: http://www.opensource.org/licenses/mit-license.php * GPL License: http://www.gnu.org/copyleft/gpl.html * * Date: 2009-08-21 */ //-------------------------------------------------------------------------------- /* Grid Class defined here. We use the Grid class to render a draggable simple data table. */ Grid = function (depth, xPos, yPos, width, height, rows, columns, cellWidth, cellHeight, allowResize, borderColor, borderAlpha, resizeBarColor, resizeBarThickness, resizeBarAlpha) { // Constructor function // Details of parameters: // Depth - Level in which the entire grid would be plotted // xPos - Starting x Position of the grid (global perspective) // yPos - Starting y Position of the grid (global perspective) // Width - Width of the grid to be drawn // Height - Height of the grid to be drawn // Rows - Number of rows that the grid would plot // Columns - Number of columns that the grid would plot // CellWidth (Array) - A single dimension array consisting width of each column // CellHeight (Array) - A single dimension array consisting required height for each row // allowResize (Boolean) - Whether to allow the users to resize the grid // borderColor, borderAlpha - Grid border properties // resizeBarColor, resizeBarThickness, resizeBarAlpha - Resize bar properties // Copy parameters to class objects this.depth = depth; this.xPos = xPos; this.yPos = yPos; this.gridWidth = width; this.gridHeight = height; this.rows = rows; this.columns = columns; this.allowResize = allowResize; // Initialize cellwidth and height as arrays this.cellWidth = new Array(); this.cellHeight = new Array(); if (cellWidth != null && cellWidth != undefined && cellWidth.length>0) { this.cellWidth = cellWidth; // Unshift the array to make it with base 1 this.cellWidth.unshift(0); } if (cellHeight != null && cellHeight != undefined && cellHeight.length>0) { this.cellHeight = cellHeight; // Unshift the array to make it with base 1 this.cellHeight.unshift(0); } this.borderColor = borderColor; this.borderAlpha = borderAlpha; // Resize bar details this.resizeBarColor = resizeBarColor; this.resizeBarThickness = resizeBarThickness; this.resizeBarAlpha = resizeBarAlpha; // Create the data container for the grid this.cells = new Array(this.rows); // Create rows x columns number of cells for (i=1; i<=this.rows; i++) { this.cells[i] = new Array(); } // Now we can refer to any cell as this.cells[r][c]. // Create a depth counter this.currDepth = 1; // Instance reference this.instance = this; // CONSTANT - Padding between the drag resize bar and column end this.resizePadding = 15; // Initialize the grid this.initialize(); }; //Create the cell object Grid.cell = function(bgColor, bgAlpha, label, font, fontColor, fontSize, align, vAlign, isBold, isUnderLine, link) { //Each cell object represents a particular cell this.bgColor = bgColor; this.bgAlpha = bgAlpha; this.label = label; this.font = font; this.fontColor = fontColor; this.fontSize = fontSize; this.align = align; this.vAlign = vAlign; this.isBold = isBold; this.isUnderLine =isUnderLine; this.link = link; //If it's underline add the tags if (this.isUnderLine==true) { this.label = "" + this.label + ""; } //Add padding //If the label is to be left aligned, add a space on the left to give padding effect //Similarly, if it's to be right aligned, add padding on the right switch (this.align.toUpperCase()) { case "LEFT" : this.label = " "+this.label; break; case "RIGHT" : this.label = this.label+" "; break; } }; Grid.prototype.initialize = function() { //Initialization of grid basically refers to calculating the various positions //and setting them as defaults if not explicitly set //First, we work on cell width //Convert all cell width to numbers var unallocatedCellWidth = 0; for (var i = 1; i<=this.columns; i++) { if (this.cellWidth[i] == "" || this.cellWidth[i] == undefined || IsNaN(this.cellWidth[i]) == true) { //Set it as 0 value this.cellWidth[i] = 0; //Increase the counter of cells whose width are unallocated unallocatedCellWidth++; } else { //Convert the existing value into numbers (to be on safe side during calculations) this.cellWidth[i] = Number(this.cellWidth[i]); //If the cell width is more than the width of the grid, re-set if (this.cellWidth[i]>this.gridWidth) { //Set it to equal distance this.cellWidth[i] = this.gridWidth/this.columns; } } } //Now, calculate the total cell width "explicitly" allotted by user var cellWidthAllocation = 0; var cellEquiWidth = 0; for (var i = 1; i<=this.columns; i++) { //Add to cellWidthAllocation cellWidthAllocation = cellWidthAllocation+this.cellWidth[i]; } //Now, divide the unallocated cell width into unallocated cells number cellEquiWidth = Math.abs(this.gridWidth-cellWidthAllocation)/unallocatedCellWidth; //Allot this equal width to cells having 0 values for (var i = 1; i<=this.columns; i++) { if (this.cellWidth[i] == 0) { this.cellWidth[i] = cellEquiWidth; } } //Do the same for height //Convert all cell height to numbers var unallocatedCellHeight = 0; for (var i = 1; i<=this.rows; i++) { if (this.cellHeight[i] == "" || this.cellHeight[i] == undefined || IsNaN(this.cellHeight[i]) == true) { //Set it as 0 value this.cellHeight[i] = 0; //Increase the counter of cells whose height are unallocated unallocatedCellHeight++; } else { //Convert the existing value into numbers (to be on safe side during calculations) this.cellHeight[i] = Number(this.cellHeight[i]); //If the cell height is more than the height of the grid, re-set if (this.cellHeight[i]>this.gridHeight) { //Set it to equal distance this.cellHeight[i] = this.gridHeight/this.rows; } } } //Now, calculate the total cell height "explicitly" allotted by user var cellHeightAllocation = 0; var cellEquiHeight = 0; for (var i = 1; i<=this.rows; i++) { //Add to cellHeightAllocation cellHeightAllocation = cellHeightAllocation+this.cellHeight[i]; } //Now, divide the unallocated cell height into unallocated cells number cellEquiHeight = Math.abs(this.gridHeight-cellHeightAllocation)/unallocatedCellHeight; //Allot this equal height to cells having 0 values for (var i = 1; i<=this.rows; i++) { if (this.cellHeight[i] == 0) { this.cellHeight[i] = cellEquiHeight; } } }; Grid.prototype.setCellData = function(rowIndex, columnIndex, bgColor, bgAlpha, label, font, fontColor, fontSize, align, vAlign, isBold, isUnderLine, link) { //This method sets the data for a paticular grid cell //Create a temporary Cell Object to represent this grid's cell var objCell = new Grid.cell(bgColor, bgAlpha, label, font, fontColor, fontSize, align, vAlign, isBold, isUnderLine, link); //Set this object in the cells array this.cells[rowIndex][columnIndex] = objCell; delete objCell; }; Grid.prototype.draw = function() { //This function actually draws the grid. //Create the container Movie clip first of all createEmptyMovieClip("Grid_"+this.depth, this.depth); //Get a reference to it var mcGrid = eval("Grid_"+this.depth); //Draw the grid background (cell & rows border line) - column wise for (var i = 1; i<=this.columns; i++) { //Create a new container for each column mcGrid.createEmptyMovieClip("Column_"+i, this.currDepth++); //Get reference var mcColumn = eval(mcGrid+".Column_"+i); //Move to initial position mcColumn.moveTo(0, 0); var currColWidth = this.cellWidth[i]; var currColHeight = 0; //Draw the cells in it for (var j = 1; j<=this.rows; j++) { //Set the line style for cell border mcColumn.lineStyle(0, parseInt(this.borderColor, 16), this.borderAlpha); //If it's to be filled, set the background color if (this.cells[j][i].bgColor != "" && this.cells[j][i].bgColor != undefined && this.cells[j][i].bgColor != null) { mcColumn.beginFill(parseInt(this.cells[j][i].bgColor, 16), this.cells[j][i].bgAlpha); } mcColumn.moveTo(0, currColHeight); mcColumn.lineTo(currColWidth, currColHeight); mcColumn.lineTo(currColWidth, currColHeight+this.cellHeight[j]); mcColumn.lineTo(0, currColHeight+this.cellHeight[j]); mcColumn.lineTo(0, currColHeight); mcColumn.endFill(); //Height currColHeight = currColHeight+this.cellHeight[j]; //End fill } //x-Position the column var columnXPos = 0; for (var k = 1; k<=i-1; k++) { columnXPos = columnXPos+this.cellWidth[k]; } mcColumn._x = columnXPos; delete mcColumn; } //Now, draw the resize bars only if there are more than 2 columns //And we have to allow resize if (this.columns>1 && this.allowResize == true) { for (var i = 2; i<=this.columns; i++) { //Create the resize bar containers mcGrid.createEmptyMovieClip("ResizeBar_"+(i-1), this.currDepth++); //Get the reference mcResizeBar = eval(mcGrid+".ResizeBar_"+(i-1)); //Create the visible and invisible parts of the resize bar //The invisible part is the one which responds to mouse events (drag) //Visible part shows up while drawing mcResizeBar.createEmptyMovieClip("HitArea", 1); mcResizeBar.createEmptyMovieClip("Bar", 2); //Get reference to both mcRBHitArea = eval(mcResizeBar+".HitArea"); mcRBBar = eval(mcResizeBar+".Bar"); //Create the lines //Hit Area mcRBHitArea.lineStyle(6, 0x000000, 0); mcRBHitArea.moveTo(0, 0); mcRBHitArea.lineTo(0, currColHeight); //Visible Bar mcRBBar.lineStyle(this.resizeBarThickness, parseInt(this.resizeBarColor, 16), this.resizeBarAlpha); mcRBBar.moveTo(0, 0); mcRBBar.lineTo(0, currColHeight); //By default the visible line won't be visible mcRBBar._visible = false; //Set the x-position of the resize bar var barXPos = 0; for (var k = 1; k<=i-1; k++) { barXPos = barXPos+this.cellWidth[k]; } mcResizeBar._x = barXPos; //Set the internal properties //Id specifies the column index it drags (column index on whose right side this is attached) mcResizeBar.id = i-1; //Start X specifies the start x position till where it will be allowed to drag mcResizeBar.startX = barXPos-this.cellWidth[i-1]; //End X specifies the end x position till where it will be allowed to drag. mcResizeBar.endX = barXPos+this.cellWidth[i]; //Center X specifies its current position mcResizeBar.centerX = barXPos; //Grid instance mcResizeBar.gridInstance = this.instance; //Now, set the event handlers. mcResizeBar.onRollOver = function() { // Hide mouse Mouse.hide(); MovResizeCursor._visible = true; MovResizeCursor._x = _xmouse; MovResizeCursor._y = _ymouse; this.onMouseMove = function() { MovResizeCursor._x = _xmouse; MovResizeCursor._y = _ymouse; }; }; mcResizeBar.onRollOut = function() { delete this.onMouseMove; // Show mouse Mouse.show(); MovResizeCursor._visible = false; }; mcResizeBar.onPress = function() { // Flag this.dragging = true; // Show the resize bar this.Bar._visible = true; // Start dragging this.startDrag(false, this.startX+this.gridInstance.resizePadding, 0, this.endX-this.gridInstance.resizePadding, 0); }; mcResizeBar.onRelease = mcResizeBar.onReleaseOutside=function () { // Flag this.dragging = false; // Stop dragging this.stopDrag(); // Set line visible false this.Bar._visible = false; // Make the size of the left column smaller var mcColumnLeft = eval(mcGrid+".Column_"+(this.id)); var mcColumnRight = eval(mcGrid+".Column_"+(this.id+1)); mcColumnLeft._width += (this._x-this.centerX); mcColumnRight._x += (this._x-this.centerX); mcColumnRight._width -= (this._x-this.centerX); // Update global cellwidth this.gridInstance.cellWidth[this.id] += (this._x-this.centerX); this.gridInstance.cellWidth[this.id+1] -= (this._x-this.centerX); // Update indexes this.centerX = this._x; this.startX = mcColumnLeft._x; this.endX = mcColumnRight._x+mcColumnRight._width; // Get reference to previous resize bar var mcPreviousLine = eval(mcGrid+".ResizeBar_"+(this.id-1)); // Set its endX position - as it can now only drag upto the centerX of the currently dragged resize bar mcPreviousLine.endX = this.centerX; // Get reference to next resize bar var mcNextLine = eval(mcGrid+".ResizeBar_"+(this.id+1)); // Set its startX position - as it can now only drag from the centerX of the currently dragged resize bar mcNextLine.startX = this.centerX; // Re-draw the text for this column and the next column this.gridInstance.drawText(this.id); this.gridInstance.drawText(this.id+1); }; } } //Shift the grid to required x and y position mcGrid._x = this.xPos; mcGrid._y = this.yPos; //Set the depth index for labels this.labelDepth = this.currDepth+1; delete mcGrid; //Draw the text for all the columns initially for (var i = 1; i<=this.columns; i++) { this.drawText(i); } }; Grid.prototype.drawText = function(columnId) { //This function renders the text in the grid for a particular column //First get the cumulative xPos of that column's center var columnCenterX = 0; //Variable to store the center y position of the row var rowCenterY = 0; for (var i = 1; i"+this.cells[i][columnId].label+"", columnCenterX, (rowCenterY+this.cellHeight[i]*0.5), this.cellWidth[columnId], this.cellHeight[i], this.cells[i][columnId].font, this.cells[i][columnId].fontSize, this.cells[i][columnId].fontColor, this.cells[i][columnId].isBold, this.cells[i][columnId].align, this.cells[i][columnId].vAlign, true); } else { //Create simple text label this.createBoundedText(this.labelDepth+((i-1)*this.columns)+columnId, this.cells[i][columnId].label, columnCenterX, (rowCenterY+this.cellHeight[i]*0.5), this.cellWidth[columnId], this.cellHeight[i], this.cells[i][columnId].font, this.cells[i][columnId].fontSize, this.cells[i][columnId].fontColor, this.cells[i][columnId].isBold, this.cells[i][columnId].align, this.cells[i][columnId].vAlign, true); } //Add the row height rowCenterY = rowCenterY+this.cellHeight[i]; } }; Grid.prototype.createBoundedText = function(depth, strText, xPos, yPos, width, height, fontFamily, fontSize, fontColor, isBold, alignPos, vAlignPos, isHTML) { //This function creates a text field according to the parameters passed //Parameters //-------------------------- //depth - movie clip depth - Number //strText - text to be displayed in the text box - string //xPos - x position of the text box - Number //yPos - y position of the text box - Number //fontFamily - font face of the text - string //fontSize - size of the text - Number //fontColor - color without # like FFFFDD, 000222 - string //isBold - bold property - boolean //alignPos - alignment position - "center", "left", or "right" - string //vAlignPos- vertical alignment position - "center", "left", or "right" - string //isHTML - option whether the text would be rendered as HTML or as text //Returns - the width,height, xPos and yPos of the textbox created //As an object with properties textWidth and textHeight //-------------------------- //First up, we get the actual pixels (width) this text will take var objT = createText(50000+depth, strText, xPos, yPos, fontFamily, fontSize, fontColor, isBold, alignPos, vAlignPos, null, isHTML); var tWidth = objT.textWidth; var tHeight = objT.textHeight; deleteText(50000+depth); //Set defaults for isBold, alignPos, vAlignPos, rotationAngle, isHTML if (isBold == undefined || isBold == null || isBold == "") { isBold = false; } alignPos = getFirstValue(alignPos, "center"); vAlignPos = getFirstValue(vAlignPos, "center"); //By default, we render all text as HTML if (isHTML == undefined || isHTML == null || isHTML == "") { isHTML = true; } //First, create a new Textformat object var fcTextFormat = new TextFormat(); //Set the properties of the text format objects fcTextFormat.font = fontFamily; fcTextFormat.color = parseInt(fontColor, 16); fcTextFormat.size = fontSize; fcTextFormat.bold = isBold; //Create a textProperties object which would be returned to the caller //to represent the text width and height var LTextProperties; LTextProperties = new Object(); //Create the actual text field object now. - a & b are undefined variables //We want the initial text field size to be flexible //Get a reference to it var mcGrid = eval("Grid_"+this.depth); mcGrid.createTextField("ASMovText_"+depth, depth, xPos, yPos, width, height); //Get a reference to the text field MC var fcText = eval(mcGrid+".ASMovText_"+depth); //Set the properties fcText.multiLine = true; fcText.selectable = false; fcText.html = isHTML; //Set the text if (isHTML) { //If it's HTML text, set as htmlText fcText.htmlText = strText; } else { //Else, set as plain text fcText.text = strText; } //Apply the text format fcText.setTextFormat(fcTextFormat); //Horizontal alignment //If the textwidth is more than width available, we just left align if (tWidth>width) { fcText._x = xPos-(width/2); } else { //Else we do the proper alignment switch (alignPos.toUpperCase()) { case "LEFT" : fcText._x = xPos-(width/2); break; case "CENTER" : fcText._x = xPos-(tWidth/2); break; case "RIGHT" : fcText._x = xPos+(width/2)-tWidth; break; } } //If the text height is greater than the height available, then just set it to center if (tHeight>height) { fcText._y = yPos-(height/2); break; } else { //Vertical alignment switch (vAlignPos.toUpperCase()) { case "LEFT" : //Left is equivalent to top (of the ypos mid line - virtual) // TEXT HERE //---------MID LINE--------- // (empty space) fcText._y = yPos-height/2; break; case "CENTER" : // (empty space) //---------TEXT HERE--------- // (empty space) fcText._y = yPos-(tHeight/2); break; case "RIGHT" : //Right is equivalent to bottom // (empty space) //---------MID LINE--------- // TEXT HERE fcText._y = yPos+height/2-tHeight; break; } } delete fcTextFormat; delete fcText; };