/** Draws the label using the specificed painter & x/y-offsets */ void MLabelObject::draw( QPainter* p, int xoffset, int yoffset ) { QFont font( fontFamily, fontSize, fontWeight, fontItalic ); QPen textPen( foregroundColor, 0, QPen::NoPen ); int tf; // Set the offsets int xcalc = xpos + xoffset; int ycalc = ypos + yoffset; // Draw the base drawBase( p, xoffset, yoffset ); // Set the font p->setFont( font ); QFontMetrics fm = p->fontMetrics(); // Set the text alignment flags // Horizontal switch ( hAlignment ) { case MLabelObject::Left: tf = QPainter::AlignLeft; break; case MLabelObject::Center: tf = QPainter::AlignHCenter; break; case MLabelObject::Right: tf = QPainter::AlignRight; } // Vertical switch ( vAlignment ) { case MLabelObject::Top: tf = tf | QPainter::AlignTop; break; case MLabelObject::Bottom: tf = tf | QPainter::AlignBottom; break; case MLabelObject::Middle: tf = tf | QPainter::AlignVCenter; } // Word wrap if ( wordWrap ) tf = tf | QPainter::WordBreak; // Draw the text p->setPen( textPen ); p->drawText( xcalc + xMargin, ycalc + yMargin, width - xMargin, height - yMargin, tf, text ); }
// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- // ---- paint // ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- void Shape::paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget ) { QPen textPen( getTextColor() ); painter->setPen( textPen ); painter->drawText ( option->rect.x() + option->rect.width ()/2 - QFontMetricsF(painter->font()).width ( getText() )/2, option->rect.y() + option->rect.height()/2 + QFontMetricsF(painter->font()).height( )/3, getText() ); }
void LogView::createHeader() { _headerScene->clear(); _hourScene->clear(); QSize size = headerSizeHint(); QLinearGradient grad(0, 0, 0, size.height()); int dark = 210; grad.setColorAt(1, QColor(dark, dark, dark)); grad.setColorAt(0.7, QColor(dark + 20, dark + 20, dark + 20)); grad.setColorAt(0, Qt::white); QBrush background(grad); QPen pen(QColor(220, 220, 220)); QSize sizeHint = _logScene->viewSizeHint(); _headerScene->addRect(0, 0, sizeHint.width() + verticalScrollBar()->width() + 200, size.height() + 1, pen, background)->setZValue(0); int columnSize = _logScene->dayWidth(); DateTime startDate = _logScene->startDate().addDays(-1); DateTime today; today.setHour(0); today.setMin(0); today.setSecs(0); for (int x = 0; x < _logScene->totalDays(); x++) { QPen textPen(Qt::black); QGraphicsSimpleTextItem* text = _headerScene->addSimpleText(startDate.addDays(1).toQDateTime().toString("dd-MMM"), QFont("Arial", 8)); text->setPos((x * columnSize + 2) + 50, 3); text->setVisible(true); // text->setPen(textPen); text->setZValue(1); if (startDate == today) { _todayPos = (x * columnSize + 2); } startDate = startDate.addDays(1); } _headerView.setMaximumHeight(headerSizeHint().height()); for (int x = 0; x < 24; x++) { _hourScene->addRect(0, x*BLOCKSIZE, 50, BLOCKSIZE, pen, background)->setZValue(0); std::stringstream ss; ss << x << ":00"; QGraphicsSimpleTextItem* text = _hourScene->addSimpleText(ss.str().c_str()); text->setPos(10, (x * BLOCKSIZE) + 10); text->setVisible(true); // text->setPen(textPen); text->setZValue(1); } _hourView.setScene(_hourScene); _hourView.setMaximumWidth(50); }
void FramesWeightFrame::drawWeights() { if(!offscreen) return; QPainter p(offscreen); QColor boxColor = QColor("#5c4179"); p.fillRect(0, 0, frames_count*FrameBarWidth, TrackHeight, boxColor); //emphasize the first frame if it's T-pose if(_anim->isFirstFrameTPose()) p.fillRect(0, 0, FrameBarWidth, TrackHeight, QColor("#84365D")); double hFactor = ((double)TrackHeight) / 100.0; QColor barColor("#999999"); for(int i=0; i<frames_count; i++) { int barHeight = (int)(frameWeights[i] * hFactor); if(i==weightedFrame) p.fillRect(i*FrameBarWidth +1, TrackHeight-barHeight, FrameBarWidth-2, barHeight, QColor("#0080ff")); else p.fillRect(i*FrameBarWidth +1, TrackHeight-barHeight, FrameBarWidth-2, barHeight, barColor); if(weightedFrame!=-1) { int w = frameWeights[weightedFrame]; QPen textPen(QColor("#f8f8f8")); QFont f ("Arial", 11, QFont::Normal); p.setPen(textPen); p.setFont(f); //for some galactic reason the center alignment doesn't work as expected, so must be done manually if(w==100) p.drawText(weightedFrame*FrameBarWidth-FrameBarWidth, TrackHeight-TextSize, FrameBarWidth*3, TextSize, Qt::AlignJustify, QString::number(w)); else if(w<10) p.drawText(weightedFrame*FrameBarWidth, TrackHeight-TextSize, FrameBarWidth, TextSize, Qt::AlignJustify, QString::number(w)); else //10-99 p.drawText(weightedFrame*FrameBarWidth-(FrameBarWidth/2), TrackHeight-TextSize, FrameBarWidth*2, TextSize, Qt::AlignJustify, QString::number(w)); } } }
void dialogAnalog::initPixmap(QSize size) { // resize the pixmap // complete it // Draw plot QPainter painter; int heightPerField = size.height() / NbBits; lastPixmap=QPixmap( size.width(), size.height() ); lastPixmap.fill(Qt::black); painter.begin(&lastPixmap); // set font ------------------------------------------------------------------------------------ QFont textFont; textFont.setPixelSize(heightPerField / 2); painter.setFont(textFont); // set the needed pens ------------------------------------------------------------------------- QPen linePen(QColor(100,100,100)); QPen textPen(QColor(255, 255, 255)); QPen gridPen(QColor(100, 100, 100)); QColor greenColor(Qt::green); QPen dataPen(greenColor); // draw the fields and the text ---------------------------------------------------------------- { int current = heightPerField; for (int i = 0; i < (NbBits - 1); i++) { painter.setPen(linePen); painter.drawLine(0, current, size.width(), current); painter.setPen(textPen); QString lbl = QString::number(i+1); if (currentlabels.contains(i+1)) lbl += "-"+currentlabels[i+1]; painter.drawText(10, current - heightPerField / 3, lbl); current += heightPerField; } painter.setPen(textPen); painter.drawText(10, current - 15, QString::number(NbBits)); } painter.end(); }
void SceneGraphConnection::paint(QPainter* painter) { painter->setRenderHints(QPainter::Antialiasing, true); if(!m_selected){ if(m_type == In) m_connFillBrush = QBrush(QColor(DESELECTED_IN_CONNECTOR_COLOR)); else m_connFillBrush = QBrush(QColor(DESELECTED_OUT_CONNECTOR_COLOR)); } else { m_connFillBrush = QBrush(QColor(SELECTED_CONNECTOR_COLOR)); } painter->setBrush(m_connFillBrush); // text block if(m_type == In) painter->drawRect(CONNECTION_WIDTH+2,0,width(),height()); else painter->drawRect(0,0,width()-CONNECTION_WIDTH,height()); QPen textPen(QColor(NODE_TEXT_COLOR),2); QFont textFont("DejaVuSans",7); painter->setPen(textPen); painter->setFont(textFont); if(m_type == In) { painter->drawText(QRect(CONNECTION_WIDTH+2,0,NODE_WIDTH/2,height()),Qt::AlignLeft|Qt::AlignVCenter,m_name); } else { painter->drawText(QRect(0,0,(NODE_WIDTH/2)-2,height()),Qt::AlignRight|Qt::AlignVCenter,m_name); } if(m_type == In) { painter->drawRect(0,0,CONNECTION_WIDTH,CONNECTION_HEIGHT); } else { painter->drawRect(NODE_WIDTH/2,0,CONNECTION_WIDTH,CONNECTION_HEIGHT); } }
/*! Draw an entry on the legend \param painter Qt Painter \param plotItem Plot item, represented by the entry \param data Attributes of the legend entry \param rect Bounding rectangle for the entry */ void QwtPlotLegendItem::drawLegendData( QPainter *painter, const QwtPlotItem *plotItem, const QwtLegendData &data, const QRectF &rect ) const { Q_UNUSED( plotItem ); const int m = d_data->itemMargin; const QRectF r = rect.toRect().adjusted( m, m, -m, -m ); painter->setClipRect( r, Qt::IntersectClip ); int titleOff = 0; const QwtGraphic graphic = data.icon(); if ( !graphic.isEmpty() ) { QRectF iconRect( r.topLeft(), graphic.defaultSize() ); iconRect.moveCenter( QPoint( iconRect.center().x(), rect.center().y() ) ); graphic.render( painter, iconRect, Qt::KeepAspectRatio ); titleOff += iconRect.width() + d_data->itemSpacing; } const QwtText text = data.title(); if ( !text.isEmpty() ) { painter->setPen( textPen() ); painter->setFont( font() ); const QRectF textRect = r.adjusted( titleOff, 0, 0, 0 ); text.draw( painter, textRect ); } }
void BpDocument::composeTable1( void ) { // 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 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 ); // Store pixel resolution into local variables. double yppi = m_screenSize->m_yppi; double xppi = m_screenSize->m_xppi; double textHt, titleHt, valueHt; textHt = ( textMetrics.lineSpacing() + m_screenSize->m_padHt ) / yppi; titleHt = ( titleMetrics.lineSpacing() + m_screenSize->m_padHt ) / yppi; valueHt = ( valueMetrics.lineSpacing() + m_screenSize->m_padHt ) / yppi; // END THE STANDARD PREAMBLE USED BY ALL TABLE COMPOSITION FUNCTIONS QString results(""); translate( results, "BpDocument:Table:Results" ); // Determine variable label, value, and units minimum column widths. int nameWdPixels = 0; int resultWdPixels = 0; int unitsWdPixels = 0; int vid, len; QString qStr; EqVar *varPtr; // Loop for each output variable. for ( vid = 0; vid < tableVars(); vid++ ) { varPtr = tableVar(vid); // Label width. len = textMetrics.width( *(varPtr->m_label) ); if ( len > nameWdPixels ) { nameWdPixels = len; } // Units width. len = textMetrics.width( varPtr->m_displayUnits ); if ( len > unitsWdPixels ) { unitsWdPixels = len; } // Value width. if ( varPtr->isContinuous() ) { qStr.sprintf( "%1.*f", varPtr->m_displayDecimals, tableVal(vid) ); len = valueMetrics.width( qStr ); if ( len > resultWdPixels ) { resultWdPixels = len; } } else if ( varPtr->isDiscrete() ) { int iid = (int) tableVal(vid); qStr = varPtr->m_itemList->itemName(iid); len = valueMetrics.width( varPtr->m_itemList->itemName(iid) ); if ( len > resultWdPixels ) { resultWdPixels = len; } } } // Add padding for differences in screen and printer font sizes int wmPad = textMetrics.width( "WM" ); unitsWdPixels += wmPad; nameWdPixels += wmPad; resultWdPixels += valueMetrics.width( "WM" ); // If the name is too wide for the page, reduce the name field width. if ( ( nameWdPixels + unitsWdPixels + resultWdPixels + 2 * m_screenSize->m_padWd ) > m_screenSize->m_bodyWd ) { nameWdPixels = m_screenSize->m_bodyWd - resultWdPixels - unitsWdPixels - 2 * m_screenSize->m_padWd; } // Convert name and units widths from pixels to inches. double resultWd = (double) resultWdPixels / xppi; double nameWd = (double) nameWdPixels / xppi; double unitsWd = (double) unitsWdPixels / xppi; // Determine offset (inches) required to horizontally center the table. double offsetX = ( m_screenSize->m_bodyWd - nameWdPixels - resultWdPixels - ( unitsWdPixels - wmPad ) - 2 * m_screenSize->m_padWd ) / ( 2. * xppi ); // Determine column offsets. double nameColX = m_pageSize->m_marginLeft + offsetX; double resultColX = nameColX + nameWd + m_pageSize->m_padWd; double unitsColX = resultColX + resultWd + m_pageSize->m_padWd; // Open the composer and start with a new page. startNewPage( results, TocListOut ); double yPos = m_pageSize->m_marginTop + titleHt; // Print the table header. m_composer->font( titleFont ); // use tableTitleFont m_composer->pen( titlePen ); // use tableTitleFontColor qStr = m_eqTree->m_eqCalc->docDescriptionStore().stripWhiteSpace(); //if ( qStr.isNull() || qStr.isEmpty() ) //{ // translate( qStr, "BpDocument:NoRunDescription" ); //} m_composer->text( m_pageSize->m_marginLeft, yPos, // start at UL corner m_pageSize->m_bodyWd, titleHt, // width and height Qt::AlignVCenter|Qt::AlignCenter, // center alignment qStr ); // display description yPos += titleHt; // Draw each output variable on its own line. m_composer->font( textFont ); m_composer->pen( textPen ); for ( vid = 0; vid < tableVars(); vid++ ) { varPtr = tableVar(vid); if ( varPtr->isDiagram() ) { continue; } // Get the next y position. if ( ( yPos += textHt ) > m_pageSize->m_bodyEnd ) { startNewPage( results, TocBlank ); yPos = m_pageSize->m_marginTop; } // Write the variable name. m_composer->font( textFont ); // use tableTextFont m_composer->pen( textPen ); // use tableTextFontColor qStr = *(varPtr->m_label); // display label text m_composer->text( nameColX, yPos, // start at UL corner nameWd, textHt, // width and height Qt::AlignVCenter|Qt::AlignLeft, // left justified qStr ); // display label text // Continuous variable value and units. if ( varPtr->isContinuous() ) { qStr.sprintf( "%1.*f", varPtr->m_displayDecimals, tableVal(vid) ); m_composer->font( valueFont ); // use tableValueFont m_composer->pen( valuePen ); // use tableValueFontColor m_composer->text( resultColX, yPos, // start at UL corner resultWd, valueHt, // width and height Qt::AlignVCenter|Qt::AlignRight, // right justified qStr ); // display value text m_composer->font( textFont ); // use tableTextFont m_composer->pen( textPen ); // use tableTextFontColor m_composer->text( unitsColX, yPos, // start at UL corner unitsWd, textHt, // width and height Qt::AlignVCenter|Qt::AlignLeft, // left justified varPtr->displayUnits() ); // display units text } // Discrete variable value name else if ( varPtr->isDiscrete() ) { int id = (int) tableVal(vid); m_composer->font( valueFont ); // use tableValueFont m_composer->pen( valuePen ); // use tableValueFontColor m_composer->text( resultColX, yPos, // start at UL corner resultWd, valueHt, // width and height Qt::AlignVCenter|Qt::AlignRight, // right justify varPtr->m_itemList->itemName(id) ); // display item name } } // Write any prescription results if ( false && property()->boolean( "tableShading" ) ) { // Get the next y position. if ( ( yPos += textHt ) > m_pageSize->m_bodyEnd ) { startNewPage( results, TocBlank ); yPos = m_pageSize->m_marginTop; } // Write the prescription label m_composer->font( textFont ); // use tableTextFont m_composer->pen( textPen ); // use tableTextFontColor translate( qStr, "BpDocument:Results:RxVar:Label" ); m_composer->text( nameColX, yPos, // start at UL corner nameWd, textHt, // width and height Qt::AlignVCenter|Qt::AlignLeft, // left justified qStr ); // display label text // Write the result translate( qStr, tableInRx(0) ? "BpDocument:Results:RxVar:Yes" : "BpDocument:Results:RxVar:No" ); m_composer->font( valueFont ); // use tableValueFont m_composer->pen( valuePen ); // use tableValueFontColor m_composer->text( resultColX, yPos, // start at UL corner resultWd, valueHt, // width and height Qt::AlignVCenter|Qt::AlignRight, // right justify qStr ); // display item name } // Be polite and stop the composer. m_composer->end(); // Write the spreadsheet files composeTable1Spreadsheet(); composeTable1Html(); return; }
void PieView::paintEvent(QPaintEvent *event) { QItemSelectionModel *selections = selectionModel(); QStyleOptionViewItem option = viewOptions(); QStyle::State state = option.state; QBrush background = option.palette.base(); QPen foreground(option.palette.color(QPalette::WindowText)); QPen textPen(option.palette.color(QPalette::Text)); QPen highlightedPen(option.palette.color(QPalette::HighlightedText)); QPainter painter(viewport()); painter.setRenderHint(QPainter::Antialiasing); painter.fillRect(event->rect(), background); painter.setPen(foreground); // Viewport rectangles QRect pieRect = QRect(margin, margin, pieSize, pieSize); QPoint keyPoint = QPoint(totalSize - horizontalScrollBar()->value(), margin - verticalScrollBar()->value()); if (validItems > 0) { painter.save(); painter.translate(pieRect.x() - horizontalScrollBar()->value(), pieRect.y() - verticalScrollBar()->value()); painter.drawEllipse(0, 0, pieSize, pieSize); double startAngle = 0.0; int row; for (row = 0; row < model()->rowCount(rootIndex()); ++row) { QModelIndex index = model()->index(row, 1, rootIndex()); double value = model()->data(index).toDouble(); if (value > 0.0) { double angle = 360*value/totalValue; QModelIndex colorIndex = model()->index(row, 0, rootIndex()); QColor color = QColor(model()->data(colorIndex, Qt::DecorationRole).toString()); if (currentIndex() == index) painter.setBrush(QBrush(color, Qt::Dense4Pattern)); else if (selections->isSelected(index)) painter.setBrush(QBrush(color, Qt::Dense3Pattern)); else painter.setBrush(QBrush(color)); painter.drawPie(0, 0, pieSize, pieSize, int(startAngle*16), int(angle*16)); startAngle += angle; } } painter.restore(); int keyNumber = 0; for (row = 0; row < model()->rowCount(rootIndex()); ++row) { QModelIndex index = model()->index(row, 1, rootIndex()); double value = model()->data(index).toDouble(); if (value > 0.0) { QModelIndex labelIndex = model()->index(row, 0, rootIndex()); QStyleOptionViewItem option = viewOptions(); option.rect = visualRect(labelIndex); if (selections->isSelected(labelIndex)) option.state |= QStyle::State_Selected; if (currentIndex() == labelIndex) option.state |= QStyle::State_HasFocus; itemDelegate()->paint(&painter, option, labelIndex); keyNumber++; } } } }
void PipelineFlowChart::paintEvent(QPaintEvent *e) { if(m_StageNames.empty()) return; QPainter p(this); p.fillRect(rect(), Qt::transparent); p.setRenderHint(QPainter::Antialiasing, true); const QRectF totalRect = totalAreaRect(); const QRectF box0Rect = boxRect(0); const qreal radius = qMin(MaxBoxCornerRadius, box0Rect.height() * BoxCornerRadiusFraction); const qreal arrowY = totalRect.y() + totalRect.height() / 2; QColor base = palette().color(QPalette::Base); QColor baseText = palette().color(QPalette::Text); QColor inactiveWin = palette().color(QPalette::Inactive, QPalette::Dark); QColor inactiveWinText = palette().color(QPalette::Inactive, QPalette::WindowText); QColor tooltip = palette().color(QPalette::ToolTipBase); QColor tooltipText = palette().color(QPalette::ToolTipText); QPen pen(baseText); QPen selectedPen(Qt::red); int num = numGaps(); for(int i = 0; i < num; i++) { if(!m_StageFlows[i] || !m_StageFlows[i + 1]) continue; float right = totalRect.x() + (i + 1) * (box0Rect.width() + boxMargin()); float left = right - boxMargin(); p.setBrush(baseText); drawArrow(p, pen, ArrowHeadSize, arrowY, left, right); } num = numItems(); for(int i = 0; i < num; i++) { QRectF boxrect = boxRect(i); QBrush backBrush(base); QPen textPen(baseText); QPen outlinePen = pen; if(!stageEnabled(i)) { backBrush.setColor(inactiveWin); textPen.setColor(inactiveWinText); } if(i == m_HoverStage) { backBrush.setColor(tooltip); textPen.setColor(tooltipText); } if(i == m_SelectedStage) { outlinePen = selectedPen; } outlinePen.setWidthF(BoxBorderWidth); p.setPen(outlinePen); p.setBrush(backBrush); p.drawRoundedRect(boxrect, radius, radius); QTextOption opts(Qt::AlignCenter); opts.setWrapMode(QTextOption::NoWrap); QString s = m_StageNames[i]; QRectF reqBox = p.boundingRect(QRectF(0, 0, 1, 1), m_StageNames[i], opts); if(reqBox.width() + BoxLabelMargin > (float)boxrect.width()) s = m_StageAbbrevs[i]; p.setPen(textPen); p.drawText(boxrect, s, opts); } }
void BpDocument::composeGraphBasics( Graph *g, bool isLineGraph, EqVar *xVar, EqVar *yVar, EqVar *zVar, int curves, GraphAxleParms *xParms, GraphAxleParms *yParms ) { //-------------------------------------------------------------------------- // Set the logical fonts and colors here //-------------------------------------------------------------------------- // Axis text fonts. QFont textFont( property()->string( "graphTextFontFamily" ), property()->integer( "graphTextFontSize" ) ); QPen textPen( property()->color( "graphTextFontColor" ) ); QFont axleFont( textFont ); QColor axleColor( property()->color( "graphAxleColor" ) ); QPen axlePen( axleColor, property()->integer( "graphAxleWidth" ), Qt::SolidLine ); QPen gridPen( property()->color( "graphGridColor" ), property()->integer( "graphGridWidth" ), Qt::SolidLine ); // Title fonts and colors. QFont subTitleFont( property()->string( "graphSubtitleFontFamily" ), property()->integer( "graphSubtitleFontSize" ) ); QColor subTitleColor( property()->color( "graphSubtitleFontColor" ) ); QFont titleFont( property()->string( "graphTitleFontFamily" ), property()->integer( "graphTitleFontSize" ) ); QColor titleColor( property()->color( "graphTitleFontColor" ) ); // Background and canvas colors. QBrush worldBg( property()->color( "graphBackgroundColor" ), Qt::SolidPattern ); QBrush canvasBg( "white", SolidPattern ); QPen canvasBox( "black", 1, NoPen ); //-------------------------------------------------------------------------- // Create the graph canvas, world, and decoration. //-------------------------------------------------------------------------- // Get the x- and y-axle parameters double xValMin = xParms->m_axleMin; double xValMax = xParms->m_axleMax; double xMajorStep = xParms->m_majorStep; int xDec = xParms->m_decimals; double yValMin = yParms->m_axleMin; double yValMax = yParms->m_axleMax; double yMajorStep = yParms->m_majorStep; int yDec = yParms->m_decimals; // Graph title and subtitle. QString qStr = m_eqTree->m_eqCalc->docDescriptionStore().stripWhiteSpace(); //if ( qStr.isNull() || qStr.isEmpty() ) //{ // translate( qStr, "BpDocument:NoRunDescription" ); //} g->setTitle( qStr, titleFont, titleColor ); if ( property()->boolean( "graphTitleActive" ) ) { QString text(""); translate( text, "BpDocument:Graphs:By" ); qStr = *(yVar->m_label) + "\n" + text + " " + *(xVar->m_label); if ( curves > 1 && isLineGraph && zVar ) { translate( text, "BpDocument:Graphs:And" ); qStr += "\n" + text + " " + *(zVar->m_label); } g->setSubTitle( qStr, subTitleFont, subTitleColor ); } // Use portrait orientation (assuming screen output, not printer). g->setCanvasRotation( 0.0 ); g->setCanvasScale( 1.0, 1.0 ); // NOTE: to change the graph location or size, // we must manipulate the m_composer->graph() args! g->setCanvas( m_screenSize->m_marginLeft, // upper left X pixel m_screenSize->m_marginTop, // upper left Y pixel m_screenSize->m_bodyWd, // graph canvas width in pixels m_screenSize->m_bodyHt, // graph canvas height in pixels 0 // graph border in pixels ); // Canvas background and box. g->setCanvasBg( canvasBg ); g->setCanvasBox( canvasBox ); // Make the world coordinate system 20% larger than the data range. g->setWorld( xValMin - 0.2 * (xValMax-xValMin), // canvas WORLD left coordinate yValMin - 0.2 * (yValMax-yValMin), // canvas WORLD bottom coordinate xValMax + 0.1 * (xValMax-xValMin), // canvas WORLD right coordinate yValMax + 0.1 * (yValMax-yValMin) // canvas WORLD top coordinate ); // Provide a colored background for the graph area. g->setWorldBg( xValMin, // colored bg WORLD left coordinate yValMin, // colored bg WORLD bottom coordinate xValMax, // colored bg WORLD right coordinate yValMax, // colored bg WORLD top coordinate worldBg // brush color and pattern ); //-------------------------------------------------------------------------- // Create a bottom axle with endpoints in WORLD coordinates (not AXLE). // This has all elements of an axle EXCEPT a minor grid and subtitle. //-------------------------------------------------------------------------- GraphAxle *b = g->addGraphAxle( xValMin, // axle's min scale (NOT WORLD) value xValMax, // axle's max scale (NOT WORLD) value axlePen // axle line pen (color, width, style) ); b->setWorld( xValMin, // axle's start WORLD x coordinate yValMin, // axle's start WORLD y coordinate xValMax, // axle's end WORLD x coordinate yValMin // axle's end WORLD y coordinate ); // Line graph bottom axles need labels and tic marks. if ( isLineGraph ) { b->setMajorLabels( axleFont, // label font axleColor, // font color xDec // decimal places (-1 mean no label) ); b->setMajorTics( GraphAxleBottom, // side of axle to draw tic marks xValMin, // first tic mark location in AXLE units xValMax, // last tic mark location in AXLE units xMajorStep, // tic spacing in AXLE units 0.05 * (yValMax-yValMin), // tic mark length in Y WORLD units axlePen // tic pen (color, width, style) ); b->setMinorTics( GraphAxleBottom, // side of axle to draw tic marks xValMin, // first tic mark location in AXLE units xValMax, // last tic mark location in AXLE units 0.50 * xMajorStep, // tic spacing in AXLE units 0.03 * (yValMax-yValMin), // tic mark length in Y WORLD units axlePen // tic pen (color, width, style) ); b->setMajorGrid( gridPen, // grid pen color, width, style (yValMax-yValMin) // length in Y WORLD units !! ); // Don't show the units for ratio variables. qStr = *(xVar->m_label) + " " + xVar->displayUnits(true); b->setTitle( qStr, // axle title string GraphAxleBottom, // axle side to write the string axleFont, // axle title font axleColor // axle title color ); } // Bar graphs just need the title. else { b->setTitle( *(xVar->m_label), // axle title string GraphAxleBottom, // axle side to write the string axleFont, // axle title font axleColor // axle title color ); } //-------------------------------------------------------------------------- // Create a top axle with endpoints in WORLD coordinates (not AXLE) // Same as bottom axle EXCEPT no tic labels or axle label //-------------------------------------------------------------------------- // Line graph top axles need tic marks. if ( isLineGraph ) { GraphAxle *t = g->addGraphAxle( xValMin, // axle's min scale (NOT WORLD) value xValMax, // axle's max scale (NOT WORLD) value axlePen // axle line pen (color, width, style) ); t->setWorld( xValMin, // axle's start WORLD x coordinate yValMax, // axle's start WORLD y coordinate xValMax, // axle's end WORLD x coordinate yValMax // axle's end WORLD y coordinate ); if ( false ) t->setMajorTics( GraphAxleTop, // side of axle to draw tic marks xValMin, // first tic mark location in AXLE units xValMax, // last tic mark location in AXLE units xMajorStep, // tic spacing in AXLE units 0.05 * (yValMax-yValMin), // tic mark length in WORLD units axlePen // tic pen (color, width, style) ); if ( false ) t->setMinorTics( GraphAxleTop, // side of axle to draw tic marks xValMin, // first tic mark location in AXLE units xValMax, // last tic mark location in AXLE units 0.50 * xMajorStep, // tic spacing in AXLE units 0.03 * (yValMax-yValMin), // tic mark length in WORLD units axlePen // tic pen (color, width, style) ); } //-------------------------------------------------------------------------- // Create a left axle with endpoints in WORLD coordinates (not AXLE) // This has all elements of an axle EXCEPT a minor grid and subtitle //-------------------------------------------------------------------------- GraphAxle *l = g->addGraphAxle( yValMin, // axle's min scale (NOT WORLD) value yValMax, // axle's max scale (NOT WORLD) value axlePen // axle line pen (color, width, style) ); l->setWorld( xValMin, // axle's start WORLD x coordinate yValMin, // axle's start WORLD y coordinate xValMin, // axle's end WORLD x coordinate yValMax // axle's end WORLD y coordinate ); l->setMajorLabels( axleFont, // label font axleColor, // font color yDec // decimal places (-1 mean no label) ); l->setMajorTics( GraphAxleLeft, // side of axle to draw tic marks yValMin, // first tic mark location in AXLE units yValMax, // last tic mark location in AXLE units yMajorStep, // tic spacing in AXLE units 0.04 * (xValMax-xValMin), // tic mark length in X WORLD units axlePen // tic pen (color, width, style) ); l->setMinorTics( GraphAxleLeft, // side of axle to draw tic marks yValMin, // first tic mark location in AXLE units yValMax, // last tic mark location in AXLE units 0.50 * yMajorStep, // tic spacing in AXLE units 0.02 * (xValMax-xValMin), // tic mark length in X WORLD units axlePen // tic pen (color, width, style) ); l->setMajorGrid( gridPen, // grid pen color, width, style (xValMax-xValMin) // length in X axis WORLD units !! ); // Don't show the units for fraction or ratio variables. qStr = *(yVar->m_label) + " " + yVar->displayUnits(true); l->setTitle( qStr, // axle title string GraphAxleLeft, // axle side to write the string axleFont, // axle title font axleColor // axle title font color ); //-------------------------------------------------------------------------- // Create a right axle with endpoints in WORLD coordinates (not AXLE) // Same as the left axle EXCEPT no tic labels or axle label. //-------------------------------------------------------------------------- GraphAxle *r = g->addGraphAxle( yValMin, // axle's min scale (NOT WORLD) value yValMax, // axle's max scale (NOT WORLD) value axlePen // axle line pen (color, width, style) ); r->setWorld( xValMax, // axle's start WORLD x coordinate yValMin, // axle's start WORLD y coordinate xValMax, // axle's end WORLD x coordinate yValMax // axle's end WORLD y coordinate ); if ( false ) r->setMajorTics( GraphAxleRight, // side of axle to draw tic marks yValMin, // first tic mark location in AXLE units yValMax, // last tic mark location in AXLE units yMajorStep, // tic spacing in AXLE units 0.04 * (xValMax-xValMin), // tic mark length in X WORLD units axlePen // tic pen (color, width, style) ); if ( false ) r->setMinorTics( GraphAxleLeft, // side of axle to draw tic marks yValMin, // first tic mark location in AXLE units yValMax, // last tic mark location in AXLE units 0.50 * yMajorStep, // tic spacing in AXLE units 0.02 * (xValMax-xValMin), // tic mark length in X WORLD units axlePen // tic pen (color, width, style) ); return; }
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::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 CtrlDisAsmView::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setBrush(Qt::white); painter.setPen(Qt::white); painter.drawRect(rect()); struct branch { int src,dst,srcAddr; bool conditional; }; branch branches[256]; int numBranches=0; int width = rect().width(); int numRows=(rect().height()/rowHeight); QColor bgColor(0xFFFFFFFF); QPen nullPen(bgColor); QPen currentPen(QColor(0,0,0)); QPen selPen(QColor(0xFF808080)); QPen condPen(QColor(0xFFFF3020)); QBrush lbr; lbr.setColor(bgColor); QBrush currentBrush(QColor(0xFFFFEfE8)); QBrush pcBrush(QColor(0xFF70FF70)); QFont normalFont("Arial", 10); QFont boldFont("Arial", 10); QFont alignedFont("Monospace", 10); alignedFont.setStyleHint(QFont::Monospace); boldFont.setBold(true); painter.setFont(normalFont); QImage breakPoint(":/resources/breakpoint.ico"); int i; curAddress&=~(align-1); align=(debugger->getInstructionSize(0)); for (i=0; i<=numRows; i++) { unsigned int address=curAddress + (i-(numRows/2))*align; int rowY1 = rect().top() + rowHeight*i; int rowY2 = rect().top() + rowHeight*i + rowHeight - 1; lbr.setColor((unsigned int)marker == address ? QColor(0xFFFFEEE0) : QColor(debugger->getColor(address))); QColor bg = lbr.color(); painter.setBrush(currentBrush); painter.setPen(nullPen); painter.drawRect(0,rowY1,16-1,rowY2-rowY1); if (selecting && address == (unsigned int)selection) painter.setPen(selPen); else { if(i==numRows/2) painter.setPen(currentPen); else painter.setPen(bg); } painter.setBrush(QBrush(bg)); if (address == debugger->getPC()) { painter.setBrush(pcBrush); } painter.drawRect(16,rowY1,width-16-1,rowY2-rowY1); painter.setBrush(currentBrush); QPen textPen(QColor(halfAndHalf(bg.rgba(),0))); painter.setPen(textPen); painter.setFont(alignedFont); painter.drawText(17,rowY1-3+rowHeight,QString("%1").arg(address,8,16,QChar('0'))); painter.setFont(normalFont); textPen.setColor(QColor(0xFF000000)); painter.setPen(textPen); if (debugger->isAlive()) { const char *dizz = debugger->disasm(address, align); char dis[512]; strcpy(dis, dizz); char *dis2 = strchr(dis,'\t'); char desc[256]=""; if (dis2) { *dis2=0; dis2++; const char *mojs=strstr(dis2,"->$"); if (mojs) { for (int i=0; i<8; i++) { bool found=false; for (int j=0; j<22; j++) { if (mojs[i+3]=="0123456789ABCDEFabcdef"[j]) found=true; } if (!found) { mojs=0; break; } } } if (mojs) { int offs; sscanf(mojs+3,"%08x",&offs); branches[numBranches].src=rowY1 + rowHeight/2; branches[numBranches].srcAddr=address/align; branches[numBranches].dst=(int)(rowY1+((s64)offs-(s64)address)*rowHeight/align + rowHeight/2); branches[numBranches].conditional = (dis[1]!=0); //unconditional 'b' branch numBranches++; const char *t = debugger->getDescription(offs).c_str(); if (memcmp(t,"z_",2)==0) t+=2; if (memcmp(t,"zz_",3)==0) t+=3; sprintf(desc,"-->%s", t); textPen.setColor(QColor(0xFF600060)); painter.setPen(textPen); } else { textPen.setColor(QColor(0xFF000000)); painter.setPen(textPen); } painter.drawText(149,rowY1-3+rowHeight,QString(dis2)); } textPen.setColor(QColor(0xFF007000)); painter.setPen(textPen); painter.setFont(boldFont); painter.drawText(84,rowY1-3+rowHeight,QString(dis)); painter.setFont(normalFont); if (desc[0]==0) { const char *t = debugger->getDescription(address).c_str(); if (memcmp(t,"z_",2)==0) t+=2; if (memcmp(t,"zz_",3)==0) t+=3; strcpy(desc,t); } if (memcmp(desc,"-->",3) == 0) { textPen.setColor(QColor(0xFF0000FF)); painter.setPen(textPen); } else { textPen.setColor(halfAndHalf(halfAndHalf(bg.rgba(),0),bg.rgba())); painter.setPen(textPen); } if (strlen(desc)) painter.drawText(std::max(280,width/3+190),rowY1-3+rowHeight,QString(desc)); if (debugger->isBreakpoint(address)) { painter.drawImage(2,rowY1+2,breakPoint); } } } for (i=0; i<numBranches; i++) { painter.setPen(branches[i].conditional ? condPen : currentPen); int x=280+(branches[i].srcAddr%9)*8; QPoint curPos(x-2,branches[i].src); if (branches[i].dst<rect().bottom()+200 && branches[i].dst>-200) { painter.drawLine(curPos, QPoint(x+2,branches[i].src)); curPos = QPoint(x+2,branches[i].src); painter.drawLine(curPos, QPoint(x+2,branches[i].dst)); curPos = QPoint(x+2,branches[i].dst); painter.drawLine(curPos, QPoint(x-4,branches[i].dst)); curPos = QPoint(x,branches[i].dst-4); painter.drawLine(curPos, QPoint(x-4,branches[i].dst)); curPos = QPoint(x-4,branches[i].dst); painter.drawLine(curPos, QPoint(x+1,branches[i].dst+5)); } else { painter.drawLine(curPos, QPoint(x+4,branches[i].src)); } } }
/** Draws the label using the specificed painter & x/y-offsets */ void MLabelObject::draw(QPainter* p, int xoffset, int yoffset){ QFont font(fontFamily, fontSize, fontWeight, fontItalic); QPen textPen(foregroundColor, 0, QPen::NoPen); int tf; // Set the offsets int xcalc = xpos + xoffset; int ycalc = ypos + yoffset; // Draw the base drawBase(p, xoffset, yoffset); // Set the font p->setFont(font); QFontMetrics fm = p->fontMetrics(); // Set the text alignment flags // Horizontal switch(hAlignment){ case MLabelObject::Left: tf = QPainter::AlignLeft; break; case MLabelObject::Center: tf = QPainter::AlignHCenter; break; case MLabelObject::Right: tf = QPainter::AlignRight; } // Vertical switch(vAlignment){ case MLabelObject::Top: tf = tf | QPainter::AlignTop; break; case MLabelObject::Bottom: tf = tf | QPainter::AlignBottom; break; case MLabelObject::Middle: tf = tf | QPainter::AlignVCenter; } // Word wrap if(wordWrap) tf = tf | QPainter::WordBreak; // Draw the text p->setPen(textPen); QString newtext = text; newtext.replace( QRegExp( "<br>", false ), QString( "\n" ) ); p->drawText(xcalc + xMargin, ycalc + yMargin, width - xMargin, height - yMargin, tf, newtext); // leave this in place - possible use for other tags // // // ---------------------------------------- // // look for line breaks (<br>) // // ---------------------------------------- // int idx = 0; // int ysub = ycalc; // int line_height = height; // int len = text.length(); // int line_len = len; // QString sep = "<br>"; // int len_sep = sep.length(); // while ( idx < len ) // { // int eol = text.find( sep, idx, FALSE ); // if ( eol < 0 ) // eol = len; // line_len = eol - idx; // // draw the line and determine the space used. // QRect brect = p->boundingRect(xcalc + xMargin, ysub + yMargin, // width - xMargin, line_height - yMargin, // tf, text.mid( idx, line_len ), line_len); // p->drawText( xcalc + xMargin, ysub + yMargin, // width - xMargin, line_height - yMargin, // tf, text.mid( idx, line_len ), line_len ); // // substract the vert space used. // ysub += brect.height(); // line_height -= brect.height(); // // nothing more // if ( eol == len ) // break; // else // idx = eol + len_sep; // } }
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; }
void ColorGridView::paintEvent(QPaintEvent *event) { // To make it clear, we do not use delegate at all // QItemSelectionModel *selections = selectionModel(); QStyleOptionViewItem option = viewOptions(); QStyle::State state = option.state; QBrush background = option.palette.base(); QPen foreground(option.palette.color(QPalette::WindowText)); QPen textPen(option.palette.color(QPalette::Text)); QPen highlightedPen(option.palette.color(QPalette::HighlightedText)); QPainter painter(viewport()); // close anti aliasing to make it more clear // painter.setRenderHint(QPainter::Antialiasing); painter.fillRect(event->rect(), background); painter.setPen(Qt::white); QBrush brush; brush.setTextureImage(backgroundImg); painter.setBrush(brush); painter.translate(margin - horizontalScrollBar()->value(), margin - verticalScrollBar()->value()); for(int i = 0; i<gridCount; ++i){ for(int j=0; j<gridCount; ++j){ painter.drawImage(i*(gridMargin+gridWidth),j*(gridMargin+gridWidth), backgroundImg); } } if( !model() )return; for (int row = 0; row < model()->rowCount(rootIndex()); ++row) { for(int column = 0; column < model()->columnCount(rootIndex()); ++column) { QModelIndex index = model()->index(row, column, rootIndex()); QColor color = model()->data(index).value<QColor>(); int j = index.row(); int i = index.column(); if(color.isValid()){ //draw white background to prevent disturbings of background if transparent color painter.setBrush(Qt::white); painter.drawRect(i*(gridMargin+gridWidth),j*(gridMargin+gridWidth), gridWidth,gridWidth); painter.setBrush(color); painter.drawRect(i*(gridMargin+gridWidth),j*(gridMargin+gridWidth), gridWidth,gridWidth); } } } QModelIndexList list = selectedIndexes(); if( !list.isEmpty() ){ QModelIndex index = list.at(0); // Qt::ItemFlags flags = index.flags(); // if(flags.testFlag(QItemSelectionModel::Select)){ painter.setPen(textPen); // } // if(flags.testFlag(QItemSelectionModel::Toggle)){ // painter.setPen(highlightedPen); // } int row = index.row(); int column = index.column(); // QPointF start(column*(gridMargin+gridWidth),row*(gridMargin+gridWidth)); // QRadialGradient gradient(start+QPointF(gridWidth/2,gridWidth/2),0.1,start+QPointF(gridWidth,gridWidth)); // gradient.setColorAt(0.5,Qt::transparent); // gradient.setColorAt(1.0,Qt::black); // foreground = QPen(Qt::black); // QBrush brush(gradient); // brush.setStyle(Qt::RadialGradientPattern); painter.setBrush(Qt::NoBrush); // painter.setBrush(brush); painter.drawRect(column*(gridMargin+gridWidth),row*(gridMargin+gridWidth), gridWidth,gridWidth); } }
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; }