void BpDocument::barYMinMax( int yid, double &yMin, double &yMax ) { // Store the x-variable range and step size in locals. int bars = ( tableRows() < graphMaxBars ) ? tableRows() : graphMaxBars ; int vid = yid; int vStep = tableVars(); double val; yMin = yMax = tableVal( yid ); for ( int row = 1; row <= bars; row++ ) { val = tableVal( vid ); vid += vStep; yMin = ( val < yMin ) ? val : yMin; yMax = ( val > yMax ) ? val : yMax; } return; }
void BpDocument::graphYMinMax( int yid, double &yMin, double &yMax ) { // Store the step size and number of curves int vStep = tableCols() * tableVars(); int curves = ( tableCols() < graphMaxLines ) ? ( tableCols() ) : graphMaxLines; bool firstOne = true; double val; int vid; yMin = yMax = 0.; // Loop for each zVar family curve value in this graph (or at least once!). // Note that zVar count is in tableCols(), e.g. each column stores a curve, // and zVar values are in tableCol( col ). for ( int col = 0; col < curves; col++ ) { // tableVal( vid ) offset of first y-value for this curve. vid = yid + col * tableVars(); // Examine every y point for this curve. // Note number of points is in tableRows(). for ( int point = 0; point < tableRows(); point++ ) { val = tableVal( vid ); vid += vStep; // If this is the first point, initialize yMin and yMax. if ( firstOne ) { yMin = yMax = val; firstOne = false; } // otherwise accumulate yMin and yMax. else { yMin = ( val < yMin ) ? val : yMin; yMax = ( val > yMax ) ? val : yMax; } } } // Next z-variable curve. return; }
void BpDocument::composeLineGraph( int yid, EqVar *xVar, EqVar *yVar, EqVar *zVar, GraphAxleParms *xParms, GraphAxleParms *yParms ) { //-------------------------------------------------------------------------- // 1: Set up fonts, pens, and colors used by this graph //-------------------------------------------------------------------------- // Graph fonts QFont textFont( property()->string( "graphTextFontFamily" ), property()->integer( "graphTextFontSize" ) ); QColor textColor( property()->color( "graphTextFontColor" ) ); QPen textPen( textColor ); // How many colors are requested? QString colorName( property()->color( "graphLineColor" ) ); int colors = 1; if ( colorName == "rainbow" ) { colors = property()->integer( "graphRainbowColors" ); } // Allocate number of requested colors. QColor *color = new QColor [colors]; checkmem( __FILE__, __LINE__, color, "QColor color", colors ); int colorId = 0; // If only 1 color... if ( colors == 1 ) { color[0].setNamedColor( colorName ); } // else if rainbow colors are requested... else { // todo - add some code to check conflicts with graphBackgroundColor // and graphGridColor (if graphGridWidth > 0 ). int hue = 0; for ( colorId = 0; colorId < colors; colorId++ ) { color[colorId].setHsv( hue, 255, 255); hue += 360 / colors; } colorId = 0; } // Set up line width and color int lineWidth = property()->integer( "graphLineWidth" ); QPen pen( color[0], lineWidth, SolidLine ); //-------------------------------------------------------------------------- // 2: Create the graph and add its curves. //-------------------------------------------------------------------------- // Initialize graph and variables Graph g; GraphLine *line[graphMaxLines]; double l_x[graphMaxSteps]; double l_y[graphMaxSteps]; int curves = ( tableCols() < graphMaxLines ) ? ( tableCols() ) : ( graphMaxLines ); int points = tableRows(); int vStep = tableCols() * tableVars(); // Loop for each zVar family curve value in this graph (or at least once!). // Note that zVar count is in tableCols(), e.g. each column stores a curve, // and zVar values are in tableCol( col ). int col, vid; for ( col = 0; col < curves; col++ ) { // tableVal[] offset of first y-value for this curve. vid = yid + col * tableVars(); // Set up the y[point] array for this curve. // Note number of points is in tableRows() and // point x values are in tableRow( point ). for ( int point = 0; point < points; point++ ) { l_x[point] = tableRow( point ); l_y[point] = tableVal( vid ); vid += vStep; } // If we're out of colors, start over. if ( colorId >= colors ) { colorId = 0; } // Create a graph line (with its own copy of the data). pen.setColor( color[colorId++] ); line[col] = g.addGraphLine( points, l_x, l_y, pen ); } // Next z-variable curve. //-------------------------------------------------------------------------- // 3: Add curve labels if there is more than 1 curve. //-------------------------------------------------------------------------- QString label; if ( curves > 1 ) { colorId = 0; #define GRAPH_LABEL_METHOD_1 #ifdef GRAPH_LABEL_METHOD_1 // Label x array index step size between labels int j1 = points / curves; if ( j1 < 1 ) { j1 = 1; } // Label x array index offset int j0 = j1 / 2; #endif double xLabel, yLabel; int idx; // Loop for each z-variable curve. for ( col = 0; col < curves; col++ ) { // Get a new color for the curve. if ( colorId >= colors ) { colorId = 0; } // Set the curve label. if ( zVar->isDiscrete() ) { int iid = (int) tableCol( col ); label = zVar->m_itemList->itemName( iid ); } else if ( zVar->isContinuous() ) { int decimals = zVar->m_displayDecimals; label.sprintf( "%1.*f", zVar->m_displayDecimals, tableCol( col ) ); // Remove all trailing zeros while ( decimals && label.endsWith( "0" ) ) { label = label.left( label.length()-1 ); decimals--; } } #ifdef GRAPH_LABEL_METHOD_1 // Determine an x-axis index for the label position. idx = ( j0 + col * j1 ) % points; xLabel = line[col]->m_x[idx]; yLabel = line[col]->m_y[idx]; #endif #ifdef GRAPH_LABEL_METHOD_2 // NEW LABEL POSITIONING METHOD STARTS HERE // Find the x position where this variable has the maximum y // clearance // Loop for each x value for this curve idx = 0; double dMax = 0; double dir = 1.; double yMin = yParms->m_axleMin; double yMax = yParms->m_axleMax; for ( int row=1; row<tableRows()-1; row++ ) { // Find vertical clearance above and below this x point double y0 = m_eqTree->getResult( row, col, yid ); // Don't consider locations outside the viewport if ( y0 < yMin || y0 > yMax ) { continue; } double below = y0 - yMin; double above = yMax - y0; double dist, y1; // Loop for each family member curve for ( int c=0; c<curves; c++ ) { // Skip self if ( c == col ) { continue; } y1 = m_eqTree->getResult( row, c, yid ); y1 = ( y1 < yMax ) ? y1 : yMax; y1 = ( y1 > yMin ) ? y1 : yMin; // Shrink vertical clearance above and below this x point? if ( y0 <= y1 ) { dist = y1 - y0; above = ( dist < above ) ? dist : above; } else { dist = y0 - y1; below = ( dist < below ) ? dist : below; } } // Is this the maximum vertical clearance so far? if ( above + below > dMax ) { dMax = above + below; idx = row; dir = ( above > below ) ? 1. : -1; } } xLabel = line[col]->m_x[idx]; double offset = dir * 0.02 * ( yMax - yMin ); yLabel = line[col]->m_y[idx] + offset; #endif // Set the label text, font, color, and position. line[col]->setGraphLineLabel( label, xLabel, yLabel, textFont, QColor( color[colorId++] ) ); } // Next curve. // Add a z-variable label to the graph. label = *(zVar->m_label); if ( zVar->isContinuous() ) { label = *(zVar->m_label) + "\n" + zVar->displayUnits(true); } g.setMultipleCurveLabel( label ); } //-------------------------------------------------------------------------- // 4: Compose the graph and add an output page to draw it onto //-------------------------------------------------------------------------- composeGraphBasics( &g, true, xVar, yVar, zVar, curves, xParms, yParms ); // Create a separate output page for this graph. QString text(""); translate( text, "BpDocument:Graphs:By" ); label = *(yVar->m_label) + " " + text + " " + *(xVar->m_label); if ( curves > 1 ) { translate( text, "BpDocument:Graphs:And" ); label += " " + text + " " + *(zVar->m_label); } startNewPage( label, TocLineGraph ); // This is how we save the graph and its composer. m_composer->graph( g, m_pageSize->m_marginLeft + m_pageSize->m_bodyWd * property()->real( "graphXOffset" ), m_pageSize->m_marginTop + m_pageSize->m_bodyHt * property()->real( "graphYOffset" ), m_pageSize->m_bodyWd * property()->real( "graphScaleWidth" ), m_pageSize->m_bodyHt * property()->real( "graphScaleHeight" ) ); // Be polite and stop the composer. m_composer->end(); delete[] color; return; }
bool BpDocument::composeGraphs( bool lineGraphs, bool showDialogs ) { // Bar graph settings int tics = 2; double max = 100.; double min = 0.; // Line graph settings if ( lineGraphs ) { tics = 11; max = tableRow( tableRows()-1 ); min = tableRow(0); } GraphAxleParms *xParms = new GraphAxleParms( min, max, tics ); checkmem( __FILE__, __LINE__, xParms, "GraphAxleParms xParms", 1 ); if ( lineGraphs && min > 0. && property()->boolean( "graphXOriginAtZero" ) ) { xParms->useOrigin(); } // Determine the x-, y-, and z-variables. EqVar *xVar = m_eqTree->m_rangeVar[0]; EqVar *zVar = m_eqTree->m_rangeVar[1]; EqVar *yVar = 0; //-------------------------------------------------------------------------- // 2: Determine nice axis parameters for the x- and all the y-variables. //-------------------------------------------------------------------------- // Initialize the Y axle for each graph to a nice range QPtrList<GraphAxleParms> *yParmsList = new QPtrList<GraphAxleParms>(); yParmsList->setAutoDelete( true ); GraphAxleParms *yParms = 0; int yid; for ( yid = 0; yid < tableVars(); yid++ ) { yVar = tableVar( yid ); yParms = 0; // The yVar must be continuous. if ( yVar->isContinuous() ) { // Get Y range if ( lineGraphs ) { graphYMinMax( yid, min, max ); } else { barYMinMax( yid, min, max ); } // Determine and store nice axis parameters tics = 11; yParms = new GraphAxleParms( min, max, tics ); checkmem( __FILE__, __LINE__, yParms, "GraphAxleParms yParms", 1 ); yParmsList->append( yParms ); // If bar graph, or line graphs must start at origin if ( min > 0. ) { if ( ! lineGraphs || property()->boolean( "graphYOriginAtZero" ) ) { yParms->useOrigin(); } } // If min and max are the same, make them different if ( min == max ) { yParms->setAxle( min-1., max+1., 3 ); } } } //-------------------------------------------------------------------------- // 1: Allow the user to change the axle parameters. //-------------------------------------------------------------------------- if ( showDialogs && property()->boolean( "graphYUserRange" ) ) { GraphLimitsDialog *dialog = new GraphLimitsDialog( this, yParmsList, "graphLimitsDialog" ); checkmem( __FILE__, __LINE__, dialog, "GraphLimitsDialog dialog", 1 ); if ( dialog->exec() == QDialog::Accepted ) { dialog->store(); } delete dialog; dialog = 0; } //-------------------------------------------------------------------------- // 3: Draw each graph. //-------------------------------------------------------------------------- // Set up the progress dialog. int step = 0; int steps = tableVars(); QString text(""), button(""); if ( lineGraphs ) { translate( text, "BpDocument:Graphs:DrawingLineGraphs" ); } else { translate( text, "BpDocument:Graphs:DrawingBarGraphs" ); } translate( button, "BpDocument:Graphs:Abort" ); QProgressDialog *progress = new QProgressDialog( QString( text ).arg( steps ), button, steps ); Q_CHECK_PTR( progress ); progress->setMinimumDuration( 0 ); progress->setProgress( 0 ); // Loop for each output variable: one graph is composed per output variable. bool result = true; for ( yid = 0, yParms = yParmsList->first(); yid < tableVars(); yid++ ) { yVar = tableVar( yid ); // The yVar must be continuous. if ( yVar->isContinuous() ) { // Recompute nice Y axis //min = ( yParms->m_axleMin < yParms->m_dataMin ) // ? yParms->m_axleMin // : yParms->m_dataMin; min = yParms->m_axleMin; //max = ( yParms->m_axleMax > yParms->m_dataMax ) // ? yParms->m_axleMax // : yParms->m_dataMax; max = yParms->m_axleMax; // If min and max are the same, make them different tics = 11; if ( min == max ) { yParms->setAxle( min-1., max+1., 3 ); } // Compose this graph. if ( lineGraphs ) { composeLineGraph( yid, xVar, yVar, zVar, xParms, yParms ); } else { composeBarGraph( yid, xVar, yVar, xParms, yParms ); } // Update progress dialog. progress->setProgress( ++step ); qApp->processEvents(); if ( progress->wasCancelled() ) { result = false; break; } yParms = yParmsList->next(); } } // Cleanup and return. delete progress; progress = 0; delete xParms; xParms = 0; delete yParmsList; yParmsList = 0; return( result ); }
void BpDocument::composeBarGraph( int yid, EqVar *xVar, EqVar *yVar, GraphAxleParms *xParms, GraphAxleParms *yParms ) { //-------------------------------------------------------------------------- // 1: Set up fonts, pens, and colors used by this graph //-------------------------------------------------------------------------- // Graph fonts. QFont textFont( property()->string( "graphTextFontFamily" ), property()->integer( "graphTextFontSize" ) ); QColor textColor( property()->color( "graphTextFontColor" ) ); QPen textPen( textColor ); // How many colors are requested? QString colorName( property()->color( "graphBarColor" ) ); int colors = 1; if ( colorName == "rainbow" ) { colors = property()->integer( "graphRainbowColors" ); } // Allocate number of requested colors. QColor *color = new QColor [colors]; checkmem( __FILE__, __LINE__, color, "QColor color", colors ); int colorId = 0; // If only 1 color... if ( colors == 1 ) { color[0].setNamedColor( colorName ); } // else if rainbow colors are requested. else { // \todo - add some code to check conflicts with graphBackgroundColor // and graphGridColor (if graphGridWidth > 0 ). int hue = 0; for ( colorId = 0; colorId < colors; colorId++ ) { color[colorId].setHsv( hue, 255, 255); hue += 360 / colors; } colorId = 0; } // Setup bar brush and color QBrush barBrush( color[colorId], Qt::SolidPattern ); //-------------------------------------------------------------------------- // 2: Create the graph and its text and axles. //-------------------------------------------------------------------------- // Initialize graph and variables Graph g; int bars = ( tableRows() < graphMaxBars ) ? tableRows() : graphMaxBars ; int vStep = tableVars(); // Draw thew basic graph (axis and text) composeGraphBasics( &g, false, xVar, yVar, 0, bars, xParms, yParms ); //-------------------------------------------------------------------------- // 3: Add the bars. //-------------------------------------------------------------------------- // Each bar occupies 2/3 of its x range, plus a 1/3 padding on right. double xMin = xParms->m_axleMin; double xMax = xParms->m_axleMax; double xMinorStep = ( xMax - xMin ) / (double) ( 3 * bars + 1 ); double xMajorStep = 3. * xMinorStep; // Create each data bar and add it to the graph. double x0, x1, y0, y1, xl; double yl = 0.; double rotation = 0.; QString label; int row, vid; for ( row = 0, vid = yid; row < bars; row++, vid += vStep ) { x0 = xMin + xMinorStep + row * xMajorStep; x1 = xMin + ( row + 1 ) * xMajorStep; y0 = yParms->m_axleMin; y1 = tableVal( vid ); xl = 0.5 * (x0 + x1) ; // If we're out of colors, start over. if ( colorId >= colors ) { colorId = 0; } // Set the bar brush to this color. barBrush.setColor( color[colorId++] ); // Create the graph bar. GraphBar *bar = g.addGraphBar( x0, y0, x1, y1, barBrush, textPen ); // Create the bar label. int iid = (int) tableRow( row ); label = xVar->m_itemList->itemName( iid ); bar->setGraphBarLabel( label, xl, yl, textFont, textColor, rotation ); } //-------------------------------------------------------------------------- // 4: Add an output page on which to draw the graph. //-------------------------------------------------------------------------- // Create a separate page for this graph. QString text(""); translate( text, "BpDocument:Graphs:By" ); label = QString( "%1 %2 %3" ) .arg( *(yVar->m_label) ) .arg( text ) .arg( *(xVar->m_label) ); startNewPage( label, TocBarGraph ); // This is how we save the graph and its composer. m_composer->graph( g, m_pageSize->m_marginLeft + m_pageSize->m_bodyWd * property()->real( "graphXOffset" ), m_pageSize->m_marginTop + m_pageSize->m_bodyHt * property()->real( "graphYOffset" ), m_pageSize->m_bodyWd * property()->real( "graphScaleWidth" ), m_pageSize->m_bodyHt * property()->real( "graphScaleHeight" ) ); // Be polite and stop the composer. m_composer->end(); delete[] color; return; }
void BpDocument::composeTable3Spreadsheet( FILE *fptr, int vid, EqVar *rowVar, EqVar *colVar ) { EqVar *outVar = tableVar(vid); QString qStr; int iid; // Two blank lines between tables fprintf( fptr, "\n\n" ); fprintf( fptr, "%s\t%s\n", (*(outVar->m_label)).latin1(), ( outVar->isContinuous() ) ? outVar->displayUnits().latin1() : "" ); fprintf( fptr, "%s\t%s\n", (*(rowVar->m_label)).latin1(), ( rowVar->isContinuous() ) ? rowVar->displayUnits().latin1() : "" ); fprintf( fptr, "%s\t%s\n", (*(colVar->m_label)).latin1(), ( colVar->isContinuous() ) ? colVar->displayUnits().latin1() : "" ); // First column header row fprintf( fptr, "\n" ); fprintf( fptr, "%s\t \t%s\t%s\n", (*(rowVar->m_hdr0)).latin1(), (*(colVar->m_hdr0)).latin1(), (*(colVar->m_hdr1)).latin1() ); // Second column header row fprintf( fptr, "%s", (*(rowVar->m_hdr1)).latin1() ); int row, col; for ( col = 0; col < tableCols(); col++ ) { if ( colVar->isDiscrete() ) { iid = (int) tableCol( col ); qStr = colVar->m_itemList->itemName( iid ); } else if ( colVar->isContinuous() ) { // CDB DECIMALS MOD if ( false ) { qStr.sprintf( " %1.*f", colVar->m_displayDecimals, tableCol( col ) ); } else { qStr.sprintf( " %1.*f", m_colDecimals, tableCol( col ) ); } } fprintf( fptr, "\t%s", qStr.latin1() ); } fprintf( fptr, "\n" ); // Table body int out = vid; for ( row = 0; row < tableRows(); row++ ) { // Row value is in the first column if ( rowVar->isDiscrete() ) { iid = (int) tableRow( row ); qStr = rowVar->m_itemList->itemName( iid ); } else if ( rowVar->isContinuous() ) { // CDB DECIMALS MOD if ( false ) { qStr.sprintf( "%1.*f", rowVar->m_displayDecimals, tableRow( row ) ); } else { qStr.sprintf( "%1.*f", m_rowDecimals, tableRow( row ) ); } } fprintf( fptr, "%s", qStr.latin1() ); // Remaining columns for ( col = 0; col < tableCols(); col++ ) { if ( outVar->isDiscrete() ) { iid = (int) tableVal( out ); qStr = outVar->m_itemList->itemName( iid ); } else if ( outVar->isContinuous() ) { qStr.sprintf( "%1.*f", outVar->m_displayDecimals, tableVal( out ) ); } fprintf( fptr, "\t%s", qStr.latin1() ); out += tableVars(); } // Next table column fprintf( fptr, "\n" ); } // Next table row return; }
void BpDocument::composeTable3( int vid, EqVar *rowVar, EqVar *colVar ) { // START THE STANDARD PREAMBLE USED BY ALL TABLE COMPOSITION FUNCTIONS. // WIN98 requires that we actually create a font here and use it for // font metrics rather than using the widget's font. QFont subTitleFont( property()->string( "tableSubtitleFontFamily" ), property()->integer( "tableSubtitleFontSize" ) ); QPen subTitlePen( property()->color( "tableSubtitleFontColor" ) ); QFontMetrics subTitleMetrics( subTitleFont ); QFont textFont( property()->string( "tableTextFontFamily" ), property()->integer( "tableTextFontSize" ) ); QPen textPen( property()->color( "tableTextFontColor" ) ); QFontMetrics textMetrics( textFont ); QFont titleFont( property()->string( "tableTitleFontFamily" ), property()->integer( "tableTitleFontSize" ) ); QPen titlePen( property()->color( "tableTitleFontColor" ) ); QFontMetrics titleMetrics( titleFont ); QFont valueFont( property()->string( "tableValueFontFamily" ), property()->integer( "tableValueFontSize" ) ); QPen valuePen( property()->color( "tableValueFontColor" ) ); QFontMetrics valueMetrics( valueFont ); bool doRowBg = property()->boolean( "tableRowBackgroundColorActive" ); QBrush rowBrush( property()->color( "tableRowBackgroundColor" ), Qt::SolidPattern ); QString text(""); // Store pixel resolution into local variables. double yppi = m_screenSize->m_yppi; double xppi = m_screenSize->m_xppi; double m_padWd = m_pageSize->m_padWd; // Determine the height of the various display fonts. double textHt, titleHt, valueHt, rowHt, x0, x1; textHt = ( textMetrics.lineSpacing() + m_screenSize->m_padHt ) / yppi; titleHt = ( titleMetrics.lineSpacing() + m_screenSize->m_padHt ) / yppi; valueHt = ( valueMetrics.lineSpacing() + m_screenSize->m_padHt ) / yppi; rowHt = ( textHt > valueHt ) ? textHt : valueHt; // END THE STANDARD PREAMBLE USED BY ALL TABLE COMPOSITION FUNCTIONS. // Determine the number of rows we can display on a page. int rowsPerPage = (int) ( ( m_pageSize->m_bodyHt - 5. * titleHt - 4. * textHt ) / rowHt ); // Number of pages the table requires to accomodate all the rows. int pagesLong = 1 + (int) ( tableRows() / rowsPerPage ); // Arrays to hold the output values' column information. // Page on which the output value column appears. int *colPage = new int[ tableCols() ]; checkmem( __FILE__, __LINE__, colPage, "int colPage", tableCols() ); // Horizontal position of each output value column. double *colXPos = new double[ tableCols() ]; checkmem( __FILE__, __LINE__, colXPos, "double colXPos", tableCols() ); // Column header text. QString *colText = new QString[ tableCols() ]; checkmem( __FILE__, __LINE__, colText, "double colText", tableCols() ); // Prescription shading? bool doRx = property()->boolean( "tableShading" ); bool doBlank = property()->boolean( "tableShadingBlank" ); // Determine the row variable's (left-most) column width. int row, iid, cell; double len; QString qStr; // Start wide enough to hold the variable name and units. double rowWd = m_padWd + ( (double) headerWidth( rowVar, textMetrics ) / xppi ); // Enlarge it to hold the fattest row value. m_rowDecimals = 0; for ( row = 0; row < tableRows(); row++ ) { if ( rowVar->isDiscrete() ) { iid = (int) tableRow( row ); qStr = rowVar->m_itemList->itemName( iid ) + "MMM"; } else if ( rowVar->isContinuous() ) { // CDB DECIMALS MOD if ( false ) { qStr.sprintf( "%1.*fMMM", rowVar->m_displayDecimals, tableRow( row ) ); } else { // Start with 6 decimals for this row value int decimals = 6; qStr.sprintf( "%1.*f", decimals, tableRow( row ) ); // Remove all trailing zeros while ( qStr.endsWith( "0" ) ) { qStr = qStr.left( qStr.length()-1 ); decimals--; } // Update m_rowDecimals digits m_rowDecimals = ( decimals > m_rowDecimals ) ? decimals : m_rowDecimals; qStr.append( "MWM" ); } } len = (double) textMetrics.width( qStr ) / xppi; if ( len > rowWd ) { rowWd = len; } } // Find the fattest output value for this table variable. int col; int out = vid; EqVar *outVar = tableVar(vid); double colWd = 0; for ( row = 0; row < tableRows(); row++ ) { for ( col = 0; col < tableCols(); col++ ) { if ( outVar->isDiscrete() ) { iid = (int) tableVal( out ); qStr = outVar->m_itemList->itemName( iid ) + "WM"; } else if ( outVar->isContinuous() ) { qStr.sprintf( "%1.*fWM", outVar->m_displayDecimals, tableVal( out ) ); } len = (double) textMetrics.width( qStr ) / xppi; if ( len > colWd ) { colWd = len; } out += tableVars(); } // Next table column. } // Next table row. // Set the column header value text. m_colDecimals = 0; for ( col = 0; col < tableCols(); col++ ) { if ( colVar->isDiscrete() ) { iid = (int) tableCol( col ); colText[col] = colVar->m_itemList->itemName( iid ); } else if ( colVar->isContinuous() ) { // CDB DECIMALS MOD if ( false ) { colText[col].sprintf( " %1.*f", colVar->m_displayDecimals, tableCol( col ) ); } else { // Start with 6 decimals for this row value int decimals = 6; colText[col].sprintf( " %1.*f", decimals, tableCol( col ) ); // Remove all trailing zeros while ( colText[col].endsWith( "0" ) ) { colText[col] = colText[col].left( colText[col].length()-1 ); decimals--; } // Update Decimals digits m_colDecimals = ( decimals > m_colDecimals ) ? decimals : m_colDecimals; } } // Expand the column width to accomodate the header value text? len = (double) textMetrics.width( colText[col] ) / xppi; if ( len > colWd ) { colWd = len; } } // Next table column. // CDB DECIMALS MOD for ( col = 0; col < tableCols(); col++ ) { if ( colVar->isContinuous() ) { colText[col].sprintf( " %1.*f", m_colDecimals, tableCol( col ) ); } } // Add padding between each column. colWd += m_padWd; // Determine each column's position on each page. int pagesWide = 1; // Horizontal position of first column on the first page. double xpos = m_pageSize->m_bodyLeft + rowWd + 2. * m_padWd; for ( col = 0; col < tableCols(); col++ ) { // If past the right page edge, start a new page. if ( xpos + colWd > m_pageSize->m_bodyRight ) { // The table page width has just increased. pagesWide++; // This will be the first column on the new page. xpos = m_pageSize->m_bodyLeft + rowWd + 2. * m_padWd; } // Store the page and position of this output variable's column. colXPos[col] = xpos; colPage[col] = pagesWide; // Update the position pointer. xpos += ( 2. * m_padWd + colWd ); } // Determine the column title width (inches). double colTitleWd = textMetrics.width( *(colVar->m_label) ) / xppi; if ( ( textMetrics.width( colVar->m_displayUnits ) / xppi ) > colTitleWd ) { colTitleWd = textMetrics.width( colVar->m_displayUnits ) / xppi; } colTitleWd += ( 2. * m_padWd ); // Determine an offset shift to center each pageAcross. double *shift = new double[ pagesWide + 1 ]; checkmem( __FILE__, __LINE__, shift, "double shift", pagesWide + 1 ); for ( col = 0; col < tableCols(); col++ ) { // Table must be at least this wide. double minLeft = m_pageSize->m_bodyLeft + rowWd + 2. * m_padWd + colTitleWd; // Does it need to be wider to accomodate this column? if ( colXPos[col] + colWd > minLeft ) { minLeft = colXPos[col] + colWd; } // Just the last column of each page finally gets stored in shift[]. shift[colPage[col]] = 0.5 * ( m_pageSize->m_bodyRight - minLeft ); } // Start drawing the table. double yPos, s, bgLeft, bgRight, rightEdge, leftEdge; int i; // Loop for each page down. int thisPage = 1; for ( int pageDown = 1; pageDown <= pagesLong; pageDown++ ) { // Loop for each page across. for ( int pageAcross = 1; pageAcross <= pagesWide; pageAcross++, thisPage++ ) { // Table title indicates the table portion translate( text, "BpDocument:Table:PageOf", *(tableVar(vid)->m_label), QString( "%1" ).arg( thisPage ), QString( "%1" ).arg( pagesLong * pagesWide ) ); // Start a new page startNewPage( text, TocTable ); yPos = m_pageSize->m_marginTop + titleHt; // Draw a map of where we are. composePageMap( ( 2. * titleHt - 0.1 ), pagesLong, pagesWide, pagesLong, pagesWide, 1, 1, pageDown-1, pageAcross-1 ); // Display the table title::description m_composer->font( titleFont ); // use tableTitleFont m_composer->pen( titlePen ); // use tableTitleFontColor qStr = m_eqTree->m_eqCalc->docDescriptionStore().stripWhiteSpace(); m_composer->text( m_pageSize->m_marginLeft, yPos, // start at UL corner m_pageSize->m_bodyWd, titleHt,// width and height Qt::AlignVCenter|Qt::AlignHCenter, // center alignement qStr ); // display description yPos += titleHt; // Display the table title::variable m_composer->font( subTitleFont ); // use tableSubtitleFont m_composer->pen( subTitlePen ); // use tableSubtitleFontColor qStr = *(outVar->m_label); if ( outVar->isContinuous() ) { qStr = *(outVar->m_label) + " " + outVar->displayUnits(true); } m_composer->text( m_pageSize->m_marginLeft, yPos, // start at UL corner m_pageSize->m_bodyWd, titleHt,// width and height Qt::AlignVCenter|Qt::AlignHCenter, // center alignment qStr ); // table variable name yPos += titleHt; // Display the table title::portion //m_composer->text( // m_pageSize->m_marginLeft, yPos, // m_pageSize->m_bodyWd, titleHt, // Qt::AlignVCenter|Qt::AlignHCenter, // portion ); //yPos += titleHt; yPos += titleHt; // Everything else on this page is shifted s = shift[pageAcross]; // Determine left and right edges of the table. leftEdge = -1; for ( col = 0; col < tableCols(); col++ ) { if ( pageAcross == colPage[col] ) { rightEdge = colXPos[col] + colWd + s; if ( leftEdge < 0. ) { leftEdge = colXPos[col] + s; } } } // Must be at least wide enough to accomodate column header text. if ( rightEdge < leftEdge + colTitleWd ) { rightEdge = leftEdge + colTitleWd; } bgLeft = m_pageSize->m_marginLeft + s - m_padWd ; bgRight = rightEdge - leftEdge + rowWd + 4 * m_padWd ; // Display a colored row column header background? if ( doRowBg ) { m_composer->fill( bgLeft, yPos, bgRight, 3 * textHt, rowBrush ); } // Display the row column header0. m_composer->font( textFont ); // use tableTextFont m_composer->pen( textPen ); // use tableTextFontColor m_composer->text( m_pageSize->m_marginLeft + s, yPos, rowWd, textHt, Qt::AlignVCenter|Qt::AlignLeft, *(rowVar->m_hdr0) ); // Display the row column header1. m_composer->text( m_pageSize->m_marginLeft + s, yPos + textHt, rowWd, textHt, Qt::AlignVCenter|Qt::AlignLeft, *(rowVar->m_hdr1) ); // Display the row column units. m_composer->text( m_pageSize->m_marginLeft + s, yPos + 2. * textHt, rowWd, textHt, Qt::AlignVCenter|Qt::AlignLeft, rowVar->displayUnits() ); // Display the row column header underline // only if we are not coloring row backgrounds. int skipLines = 3; if ( ! doRowBg ) { m_composer->line( m_pageSize->m_marginLeft + s, yPos + 3.5 * textHt, m_pageSize->m_marginLeft + rowWd + s, yPos + 3.5 * textHt ); skipLines = 4; } // Display the output column headers. for ( col = 0; col < tableCols(); col++ ) { if ( pageAcross == colPage[col] ) { // Display the output column units. m_composer->text( colXPos[col] + s, yPos + 2. * textHt, colWd, textHt, Qt::AlignVCenter|Qt::AlignRight, colText[col] ); // Display the output column underline. if ( ! doRowBg ) { m_composer->line( colXPos[col] + s, yPos + 3.5 * textHt, colXPos[col] + colWd + s, yPos + 3.5 * textHt ); } } } // Display a centered column variable name and units header. m_composer->text( leftEdge, yPos, ( rightEdge - leftEdge ), textHt, Qt::AlignVCenter|Qt::AlignHCenter, *(colVar->m_label) ); if ( colVar->isContinuous() ) { m_composer->text( leftEdge, yPos + textHt, ( rightEdge - leftEdge ), textHt, Qt::AlignVCenter|Qt::AlignHCenter, colVar->displayUnits() ); } // If there are previous columns, display a visual cue. if ( pageAcross > 1 ) { for ( i = 0; i < 3; i++ ) { m_composer->text( 0, ( yPos + i * textHt ), ( m_pageSize->m_marginLeft + s - m_padWd ), textHt, Qt::AlignVCenter|Qt::AlignRight, "<" ); } } // If there are subsequent column pages, display a visual clue. if ( pageAcross < pagesWide ) { for ( i = 0; i < 3; i++ ) { m_composer->text( ( rightEdge + m_padWd ), ( yPos + i * textHt ), ( m_pageSize->m_pageWd - rightEdge ), textHt, Qt::AlignVCenter|Qt::AlignLeft, ">" ); } } // Set vertical start of rows. yPos += skipLines * textHt; // Determine the rows range to display on this page. int rowFrom = ( pageDown - 1 ) * rowsPerPage; int rowThru = pageDown * rowsPerPage - 1; if ( rowThru >= tableRows() ) { rowThru = tableRows() - 1; } // Determine the columns range to display on this page. int colFrom = -1; int colThru = 0; for ( col = 0; col < tableCols(); col++ ) { if ( colPage[col] == pageAcross ) { if ( colFrom == -1 ) { colFrom = col; } colThru = col; } } // Loop for each row on this page. bool doThisRowBg = false; for ( row = rowFrom; row <= rowThru; row++ ) { // Display a colored row background? if ( doRowBg && doThisRowBg ) { m_composer->fill( bgLeft, yPos, bgRight, textHt, rowBrush ); } doThisRowBg = ! doThisRowBg; // Left-most (row variable) column value. if ( rowVar->isDiscrete() ) { iid = (int) tableRow( row ); qStr = rowVar->m_itemList->itemName( iid ); } else if ( rowVar->isContinuous() ) { // CDB DECIMALS MOD if ( false ) { qStr.sprintf( "%1.*f", rowVar->m_displayDecimals, tableRow( row ) ); } else { qStr.sprintf( "%1.*f", m_rowDecimals, tableRow( row ) ); } } m_composer->font( textFont ); // use tableTextFont m_composer->pen( textPen ); // use tableTextFontColor m_composer->text( m_pageSize->m_marginLeft + s, yPos, rowWd, textHt, Qt::AlignVCenter|Qt::AlignLeft, qStr ); // Loop for each column value on this page. m_composer->font( valueFont ); // use tableValueFont m_composer->pen( valuePen ); // use tableValueFontColor out = vid + colFrom * tableVars() + row * tableCols() * tableVars(); for ( col = colFrom; col <= colThru; col++ ) { // Determine whether to hatch this cell cell = col + row * tableCols(); bool hatch = doRx && ! tableInRx( cell ); // Discrete variables use their item name. if ( outVar->isDiscrete() ) { iid = (int) tableVal( out ); qStr = outVar->m_itemList->itemName( iid ); } // Continuous variables use the current display units format. else if ( outVar->isContinuous() ) { qStr.sprintf( " %1.*f", outVar->m_displayDecimals, tableVal( out ) ); } // Display the output value. if ( hatch && doBlank ) { // draw nothing } else { m_composer->text( colXPos[col] + s, yPos, colWd, textHt, Qt::AlignVCenter|Qt::AlignRight, qStr ); } out += tableVars(); // RX hatching if ( hatch && ! doBlank && ! outVar->isDiagram() ) { x0 = colXPos[col] + s - m_padWd; x1 = colXPos[col] + s + m_padWd + colWd; m_composer->line( x0, yPos, x1, ( yPos + textHt ) ); m_composer->line( x0, ( yPos + textHt ), x1, yPos ); } } // Next table output variable. yPos += rowHt; } // Next table row. } // Next pageAcross. } // Next pageDown. // Be polite and stop the composer. m_composer->end(); // Clean up and return. delete[] colPage; delete[] colXPos; delete[] colText; delete[] shift; return; }
void BpDocument::composeTable3Html( FILE *fptr, int vid, EqVar *rowVar, EqVar *colVar ) { EqVar *outVar = tableVar(vid); int iid; // Prescription shading? bool doRx = property()->boolean( "tableShading" ); bool doBlank = property()->boolean( "tableShadingBlank" ); QString text = ""; if ( outVar->isContinuous() ) { text = "(" + outVar->displayUnits() + ")"; } fprintf( fptr, "<!-- Begin 2-Way Output Table for %s -->\n" "<p class=\"bp2\">\n" " <h3 class=\"bp2\">Results for: %s %s</h3>\n" " <table cellpadding=\"5\" cellspacing=\"2\" border=\"0\">\n", (*(outVar->m_label)).latin1(), (*(outVar->m_label)).latin1(), text.latin1() ); // First column headers fprintf( fptr, " <tr>\n" " <td class=\"bp2hdr\" align=\"center\">\n" " %s\n" " </td>\n", (*(rowVar->m_hdr0)).latin1() ); fprintf( fptr, " <td class=\"bp2hdr\" colspan=\"%d\" align=\"center\">\n" " %s\n" " </td>\n" " </tr>\n", tableCols(), (*(colVar->m_label)).latin1() ); // Second column header fprintf( fptr, " <tr>\n" " <td class=\"bp2hdr\" align=\"center\">\n" " %s\n" " </td>\n", (*(rowVar->m_hdr1)).latin1() ); text = ""; if ( colVar->isContinuous() ) { text = colVar->displayUnits(); } fprintf( fptr, " <td class=\"bp2hdr\" colspan=\"%d\" align=\"center\">\n" " %s\n" " </td>\n" " </tr>\n", tableCols(), text.latin1() ); // Third column header // Row variable's units text = ""; if ( rowVar->isContinuous() ) { text = rowVar->displayUnits(); } fprintf( fptr, " <tr>\n" " <td class=\"bp2hdr\" align=\"center\">\n" " %s\n" " </td>\n", text.latin1() ); // Column variable values int row, col; for ( col = 0; col < tableCols(); col++ ) { if ( colVar->isDiscrete() ) { iid = (int) tableCol( col ); text = colVar->m_itemList->itemName( iid ); } else if ( colVar->isContinuous() ) { // CDB DECIMALS MOD if ( false ) { text.sprintf( " %1.*f", colVar->m_displayDecimals, tableCol( col ) ); } else { text.sprintf( " %1.*f", m_colDecimals, tableCol( col ) ); } } fprintf( fptr, " <td class=\"bp2hdr\" align=\"center\">\n" " %s\n" " </td>\n", text.latin1() ); } fprintf( fptr, " </tr>\n" ); // Table body int out = vid; for ( row = 0; row < tableRows(); row++ ) { // Row value is in the first column if ( rowVar->isDiscrete() ) { iid = (int) tableRow( row ); text = rowVar->m_itemList->itemName( iid ); } else if ( rowVar->isContinuous() ) { // CDB DECIMALS MOD if ( false ) { text.sprintf( "%1.*f", rowVar->m_displayDecimals, tableRow( row ) ); } else { text.sprintf( "%1.*f", m_rowDecimals, tableRow( row ) ); } } fprintf( fptr, " <tr>\n" " <td class=\"bp2hdr\" align=\"center\">\n" " %s\n" " </td>\n", text.latin1() ); // Remaining columns for ( col = 0; col < tableCols(); col++ ) { if ( outVar->isDiscrete() ) { iid = (int) tableVal( out ); text = outVar->m_itemList->itemName( iid ); } else if ( outVar->isContinuous() ) { text.sprintf( "%1.*f", outVar->m_displayDecimals, tableVal( out ) ); } // Display the output value. if ( doRx ) { int cell = col + row * tableCols(); if ( tableInRx( cell ) ) { fprintf( fptr, " <td class=\"bp2row%din\" align=\"center\">\n" " %s\n" " </td>\n", row%2, text.latin1() ); } else if ( doBlank ) { fprintf( fptr, " <td class=\"bp2row%dout\" align=\"center\">\n" " \n" " </td>\n", row%2 ); } else { fprintf( fptr, " <td class=\"bp2row%dout\" align=\"center\">\n" " %s\n" " </td>\n", row%2, text.latin1() ); } } else { fprintf( fptr, " <td class=\"bp2row%d\" align=\"center\">\n" " %s\n" " </td>\n", row%2, text.latin1() ); } out += tableVars(); } // Next table column fprintf( fptr, " </tr>\n" ); } // Next table row // End of the table for this variable fprintf( fptr, " </table>\n" "</p>\n" "<!-- End 2-Way Output Table for %s -->\n\n", (*(outVar->m_label)).latin1() ); return; }
void BpDocument::composeFireCharacteristicsDiagram( void ) { // Surface Module must be active and using fuel model inputs PropertyDict *prop = m_eqTree->m_propDict; if ( ! prop->boolean( "surfaceModuleActive" ) || ! prop->boolean( "surfaceCalcFireCharacteristicsDiagram" ) ) { return; } // Graph fonts. QFont textFont( property()->string( "graphTextFontFamily" ), property()->integer( "graphTextFontSize" ) ); QColor textColor( property()->color( "graphTextFontColor" ) ); QPen textPen( textColor ); QFont subTitleFont( property()->string( "graphSubtitleFontFamily" ), property()->integer( "graphSubtitleFontSize" ) ); QColor subTitleColor( property()->color( "graphSubtitleFontColor" ) ); // Open the result file QString resultFile = m_eqTree->m_resultFile; FILE *fptr = 0; if ( ! ( fptr = fopen( resultFile.latin1(), "r" ) ) ) // This code block should never be executed! { QString text(""); translate( text, "BpDocument:FireCharacteristicsDiagram:NoLogOpen", resultFile ); error( text ); return; } // Allocate ros and hpua data arrays int rows = tableRows(); int cols = tableCols(); int cells = rows * cols; double *hpua = new double[ cells ]; checkmem( __FILE__, __LINE__, hpua, "double hpua", cells ); double *ros = new double[ cells ]; checkmem( __FILE__, __LINE__, ros, "double ros", cells ); // Set the variable names we're looking for const char* hpuaName = "vSurfaceFireHeatPerUnitArea"; const char* rosName = "vSurfaceFireSpreadAtHead"; if ( prop->boolean( "surfaceConfSpreadDirInput" ) ) { rosName = "vSurfaceFireSpreadAtVector"; } // Read and store the ros and hpua values char buffer[1024], varName[128], varUnits[128]; int row, col, cell; double value; double rosMax = 0.0; double hpuaMax = 0.0; while ( fgets( buffer, sizeof(buffer), fptr ) ) { if ( strncmp( buffer, "CELL", 4 ) == 0 ) { if ( strstr( buffer, hpuaName ) ) { sscanf( buffer, "CELL %d %d %s cont %lf %s", &row, &col, varName, &value, varUnits ); cell = ( col - 1 ) + ( cols * ( row - 1) ); if ( ( hpua[ cell ] = value ) > hpuaMax ) { hpuaMax = value; } } else if ( strstr( buffer, rosName ) ) { sscanf( buffer, "CELL %d %d %s cont %lf %s", &row, &col, varName, &value, varUnits ); cell = ( col - 1 ) + ( cols * ( row - 1) ); if ( ( ros[ cell ] = value ) > rosMax ) { rosMax = value; } } } } fclose( fptr ); // Get variable pointers EqVar *hpuaVar = m_eqTree->m_varDict->find( "vSurfaceFireHeatPerUnitArea" ); EqVar *rosVar = m_eqTree->m_varDict->find( "vSurfaceFireSpreadAtHead" ); EqVar *fliVar = m_eqTree->m_varDict->find( "vSurfaceFireLineIntAtHead" ); EqVar *flVar = m_eqTree->m_varDict->find( "vSurfaceFireFlameLengAtHead" ); // Conversion factor double flFactor, fliFactor, rosFactor, hpuaFactor, offset; appSiUnits()->conversionFactorOffset( flVar->m_nativeUnits, flVar->m_displayUnits, &flFactor, &offset ); appSiUnits()->conversionFactorOffset( fliVar->m_nativeUnits, fliVar->m_displayUnits, &fliFactor, &offset ); appSiUnits()->conversionFactorOffset( hpuaVar->m_nativeUnits, hpuaVar->m_displayUnits, &hpuaFactor, &offset ); appSiUnits()->conversionFactorOffset( rosVar->m_nativeUnits, rosVar->m_displayUnits, &rosFactor, &offset ); // Determine which of four different chart scales to use static const int Scales = 4; static double RosScale[Scales] = { 100., 200., 400., 800. }; // ft/min static double HpuaScale[Scales] = { 2000., 4000., 8000., 16000. }; // Btu/ft2 double rosScale = 0.; // Max y-axis ros double hpuaScale = 0.; // Max x-axis hpua int scale; for ( scale=0; scale<Scales; scale++ ) { if ( rosMax < ( rosScale = RosScale[ scale ] ) ) { break; } } for ( scale=0; scale<Scales; scale++ ) { if ( hpuaMax < ( hpuaScale = HpuaScale[scale] ) ) { break; } } // Set axis maximums to appropriate predefined scale in display units rosMax = rosFactor * rosScale; hpuaMax = hpuaFactor * hpuaScale; double ratio = rosMax / hpuaMax; // Create the graph Graph graph; GraphLine *graphLine; GraphMarker *graphMarker; static const int Points = 100; double l_x[Points]; double l_y[Points]; // Draw the four standard hauling chart fli-fl levels static const int Lines = 4; static const double Fli[Lines] = { 100., 500., 1000., 2000. }; // Btu/ft/s static const double Fl[Lines] = { 4., 8., 11., 15. }; // ft // Create the hauling chart lines // Put Fireline Int label 65% of the way along the HPUA axis (display units) double xPosFli = 0.65 * hpuaMax; // Put Flame Length label 85% of the way along the HPUA axis (display units) double xPosFl = 0.85 * hpuaMax; // Fireline Int and Flame Length label Y positions (display units) double yPosFl[Lines], yPosFli[Lines]; // Icon locations (in display units) double xIcon[Lines+1], yIcon[Lines+1]; double diff, minDiff; QString label; QPen redPen( "red", 1 ); QColor blackColor( "black" ); int alignCenter = Qt::AlignHCenter | Qt::AlignVCenter; // Fireline intensity - flame length curves int line, point; for ( line = 0; line < Lines; line++ ) { minDiff = 999999999.; for ( point = 0; point < Points; point++ ) { // Hpua value in native units (Btu/ft2) l_x[point] = ( (point+1) * hpuaScale ) / (double) Points; // Ros value in native units (ft/min) l_y[point] = 60. * Fli[line] / l_x[point]; // Convert to display units l_x[point] *= hpuaFactor; l_y[point] *= rosFactor; // Check for curve inflection point (for icon placement) if ( ( diff = fabs( l_y[point]/l_x[point] - ratio ) ) < minDiff ) { minDiff = diff; xIcon[line+1] = l_x[point]; yIcon[line+1] = l_y[point]; } } // Create a graph line (with its own copy of the data). graphLine = graph.addGraphLine( Points, l_x, l_y, redPen ); // Fireline intensity label label = QString( "%1" ).arg( ( Fli[line] * fliFactor ), 0, 'f', 0 ); yPosFli[line] = rosFactor * ( 60. * Fli[line] / ( xPosFli / hpuaFactor ) ); graph.addGraphMarker( xPosFli, yPosFli[line], label, textFont, blackColor, alignCenter ); // Flame length label label = QString( "%1" ).arg( ( Fl[line] * flFactor ), 0, 'f', 0 ); yPosFl[line] = rosFactor * ( 60. * Fli[line] / ( xPosFl / hpuaFactor ) ); graph.addGraphMarker( xPosFl, yPosFl[line], label, textFont, blackColor, alignCenter ); } // Next line // Fireline intensity label and units translate( label, "BpDocument:FireCharacteristicsDiagram:FLI" ); graph.addGraphMarker( xPosFli, ( yPosFli[Lines-1] + 0.10 * rosMax ), label, textFont, blackColor, alignCenter ); graph.addGraphMarker( xPosFli, ( yPosFli[Lines-1] + 0.05 * rosMax ), fliVar->m_displayUnits, textFont, blackColor, alignCenter ); // Flame length label and units translate( label, "BpDocument:FireCharacteristicsDiagram:FL" ); graph.addGraphMarker( xPosFl, ( yPosFl[Lines-1] + 0.10 * rosMax ), label, textFont, blackColor, alignCenter ); graph.addGraphMarker( xPosFl, ( yPosFl[Lines-1] + 0.05 * rosMax ), flVar->m_displayUnits, textFont, blackColor, alignCenter ); // Add icons QPixmap pixmap[Lines]; pixmap[0] = QPixmap( fireman_xpm ); pixmap[1] = QPixmap( dozer_xpm ); pixmap[2] = QPixmap( torchtree_xpm ); pixmap[3] = QPixmap( mtnfire_xpm ); xIcon[0] = yIcon[0] = 0.0; for ( line=0; line<Lines; line++ ) { graphMarker = graph.addGraphMarker( xIcon[line] + ( 0.5 * ( xIcon[line+1] - xIcon[line] ) ), yIcon[line] + ( 0.5 * ( yIcon[line+1] - yIcon[line] ) ), "", textFont, blackColor, alignCenter ); graphMarker->setGraphMarkerPixmap( pixmap[line] ); } // Finally, add a marker for each output result QColor bluePen( "blue" ); for ( cell=0; cell<cells; cell++ ) { //fprintf( stderr, "%02d: %3.2f %3.2f\n", i, hpua[i], ros[i] ); graph.addGraphMarker( hpua[cell], ros[cell], QString( "%1" ).arg( cell + 1 ), textFont, bluePen, alignCenter ); } // Compose the graph EqVar *zVar = 0; GraphAxleParms xParms( 0.0, hpuaMax, 11 ); GraphAxleParms yParms( 0.0, rosMax, 11 ); composeGraphBasics( &graph, true, hpuaVar, rosVar, zVar, Lines, &xParms, &yParms ); // Create a separate page for this graph. translate( label, "BpDocument:FireCharacteristicsDiagram:Caption" ); graph.setSubTitle( label, subTitleFont, subTitleColor ); startNewPage( label, TocHaulChart ); // This is how we save the graph and its composer. m_composer->graph( graph, m_pageSize->m_marginLeft + m_pageSize->m_bodyWd * property()->real( "graphXOffset" ), m_pageSize->m_marginTop + m_pageSize->m_bodyHt * property()->real( "graphYOffset" ), m_pageSize->m_bodyWd * property()->real( "graphScaleWidth" ), m_pageSize->m_bodyHt * property()->real( "graphScaleHeight" ) ); // Be polite and stop the composer. m_composer->end(); delete[] ros; ros = 0; delete[] hpua; hpua = 0; return; }
TableStatistics::TableStatistics(ScriptingEnv *env, QWidget *parent, Table *base, Type t, QValueList<int> targets) : Table(env, 0, 0, "", parent, ""), d_base(base), d_type(t), d_targets(targets) { worksheet->setReadOnly(true); setCaptionPolicy(myWidget::Both); if (d_type == row) { setName(QString(d_base->name())+"-"+tr("RowStats")); setWindowLabel(tr("Row Statistics of %1").arg(base->name())); resizeRows(d_targets.size()); resizeCols(9); setColName(0, tr("Row")); setColName(1, tr("Cols")); setColName(2, tr("Mean")); setColName(3, tr("StandardDev")); setColName(4, tr("Variance")); setColName(5, tr("Sum")); setColName(6, tr("Max")); setColName(7, tr("Min")); setColName(8, "N"); for (unsigned i=0; i < d_targets.size(); i++) setText(i, 0, QString::number(d_targets[i]+1)); update(d_base, QString::null); } else if (d_type == column) { setName(QString(d_base->name())+"-"+tr("ColStats")); setWindowLabel(tr("Column Statistics of %1").arg(base->name())); resizeRows(d_targets.size()); resizeCols(11); setColName(0, tr("Col")); setColName(1, tr("Rows")); setColName(2, tr("Mean")); setColName(3, tr("StandardDev")); setColName(4, tr("Variance")); setColName(5, tr("Sum")); setColName(6, tr("iMax")); setColName(7, tr("Max")); setColName(8, tr("iMin")); setColName(9, tr("Min")); setColName(10, "N"); for (unsigned i=0; i < d_targets.size(); i++) { setText(i, 0, d_base->colLabel(d_targets[i])); update(d_base, d_base->colName(d_targets[i])); } } int w=9*(worksheet->horizontalHeader())->sectionSize(0); int h; if (tableRows()>11) h=11*(worksheet->verticalHeader())->sectionSize(0); else h=(tableRows()+1)*(worksheet->verticalHeader())->sectionSize(0); setGeometry(50,50,w + 45, h + 45); setColPlotDesignation(0, Table::X); setHeaderColType(); }