/* -*- C++ -*- This file is part of ViPEC Copyright (C) 1991-2000 Johan Rossouw (jrossouw@alcatel.altech.co.za) This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include using namespace std; //---------------------------------------------------------------------------- GridView::GridView( const char* name, WFlags f ) : GraphView( GraphView::gridView, name, f ) { //Nothing } //---------------------------------------------------------------------------- GridView::~GridView() { //Nothing } //---------------------------------------------------------------------------- void GridView::setDefaults() { GraphView::setDefaults(); linXAxis_ = false; xAxisMax_ = 10; xAxisMin_ = 0.1; yAxisMax_ = 10; yAxisMin_ = -10; numberXSteps_ = 10; numberYSteps_ = 5; xAxisTitle_ = ""; } //---------------------------------------------------------------------------- void GridView::setXAxisTitle(const char* value) { xAxisTitle_ = value; } //---------------------------------------------------------------------------- const QString& GridView::getXAxisTitle() const { return xAxisTitle_; } //---------------------------------------------------------------------------- void GridView::setLinXAxis(bool value) { linXAxis_ = value; } //---------------------------------------------------------------------------- bool GridView::getLinXAxis() const { return linXAxis_; } //---------------------------------------------------------------------------- void GridView::setXAxisMin(TReal value) { xAxisMin_ = value; } //---------------------------------------------------------------------------- TReal GridView::getXAxisMin() const { return xAxisMin_; } //---------------------------------------------------------------------------- void GridView::setXAxisMax(TReal value) { xAxisMax_ = value; } //---------------------------------------------------------------------------- TReal GridView::getXAxisMax() const { return xAxisMax_; } //---------------------------------------------------------------------------- void GridView::setNoXSteps(uint value) { numberXSteps_ = value; } //---------------------------------------------------------------------------- uint GridView::getNoXSteps() const { return numberXSteps_; } //---------------------------------------------------------------------------- void GridView::setYAxisMin(TReal value) { yAxisMin_ = value; } //---------------------------------------------------------------------------- TReal GridView::getYAxisMin() const { return yAxisMin_; } //---------------------------------------------------------------------------- void GridView::setYAxisMax(TReal value) { yAxisMax_ = value; } //---------------------------------------------------------------------------- TReal GridView::getYAxisMax() const { return yAxisMax_; } //---------------------------------------------------------------------------- void GridView::setNoYSteps(uint value) { numberYSteps_ = value; } //---------------------------------------------------------------------------- uint GridView::getNoYSteps() const { return numberYSteps_; } //---------------------------------------------------------------------------- void GridView::computeScaling( QPainter *p ) { QRect rect = p->window(); viewWidth_ = rect.width(); viewHeight_ = rect.height(); leftGap_ = (int)(0.10 * viewWidth_); rightGap_ = (int)(0.20 * viewWidth_); topGap_ = (int)(0.10 * viewHeight_); bottomGap_ = (int)(0.06 * viewHeight_); scale_ = std::sqrt((float)viewHeight_*viewHeight_ + viewWidth_*viewWidth_) / 600.0; //Calculate legend width QFont labelFont = getLabelFont(p->device()); QFontMetrics metrics( labelFont ); SeriesMap::Iterator it; int maxWidth = 0; for( it = seriesMap_.begin(); it != seriesMap_.end(); ++it ) { const QString& legend = it.key(); int width = metrics.width(legend); if (width>maxWidth) { maxWidth = width; } } rightGap_ = (int) floor(maxWidth+30*scale_); graphWidth_ = viewWidth_ - leftGap_ - rightGap_; graphHeight_ = viewHeight_ - topGap_ - bottomGap_; // Set scaling yScale_ = TReal(graphHeight_ - 1) / (yAxisMax_ - yAxisMin_); if (linXAxis_) { xScale_ = TReal(graphWidth_ - 1) / (xAxisMax_ - xAxisMin_); } else { xScale_ = TReal(graphWidth_ - 1) / (log10(xAxisMax_) - log10(xAxisMin_)); } } //---------------------------------------------------------------------------- QRect GridView::graphRect() { QRect rect(leftGap_, topGap_, graphWidth_, graphHeight_); return rect; } //---------------------------------------------------------------------------- bool GridView::isInsideView(const QPoint& p) { return graphRect().contains(p); } //---------------------------------------------------------------------------- QPoint GridView::toClient( TReal xValue, TReal yValue ) { int x, y; if (linXAxis_) { x = (int)floor((xValue - xAxisMin_)*xScale_); } else { x = (int)floor((log10(xValue) - log10(xAxisMin_))*xScale_); } y = (int)floor((yAxisMax_ - yValue) * yScale_); x += leftGap_; y += topGap_; QPoint clientPos(x,y); return clientPos; } //---------------------------------------------------------------------------- TComplex GridView::fromClient( int x, int y ) { TReal xValue, yValue; x -= leftGap_; y -= topGap_; // Compute X and Y values yValue = yAxisMax_ - ((TReal) y / yScale_) ; if (linXAxis_) { xValue = (TReal) x / xScale_ + xAxisMin_; } else { TReal n = (TReal) x / xScale_ + log10(xAxisMin_); xValue = pow(10,n); } TComplex value(xValue, yValue); return value; } TComplex GridView::transformCoordinates( TComplex coord ) { return coord; } void GridView::drawCursors(QPainter* p) { GraphView::drawCursors(p, cursorLegendRect_); } void GridView::print(QPainter *p) { draw(p); GraphView::drawCursors(p, cursorLegendRect_); frame_->reDraw(); } //---------------------------------------------------------------------------- //Draws the graph on the paint device //---------------------------------------------------------------------------- void GridView::draw(QPainter* p) { computeScaling(p); QFont titleFont = getTitleFont(p->device()); QFont labelFont = getLabelFont(p->device()); p->setPen( black ); // black pen outline //Draw frame p->drawRect( leftGap_, topGap_, graphWidth_, graphHeight_ ); //Draw title p->setFont( titleFont ); p->drawText(leftGap_, 0, graphWidth_, topGap_, AlignCenter, getTitle()); p->setFont( labelFont ); drawLabels(p); drawGrid(p); p->setPen( SolidLine ); // Prepare to plot data int rowNo = 0; int colorCount = 0; int legendPos = topGap_; int markerSize = (int) floor(3*scale_); int legendGap = (int) floor(10*scale_); // Setup legend font p->setFont( labelFont ); int lineSpacing = p->fontMetrics().lineSpacing(); //Plot each series SeriesMap::Iterator it; for( it = seriesMap_.begin(); it != seriesMap_.end(); ++it ) { DataVector& vector = it.data(); int markerSpace = (int)floor((double)vector.getSize() / 10); // Update pen color p->setPen( GraphUtils::getColor(colorCount) ); int x = leftGap_ + graphWidth_ + legendGap; int y = legendPos; if (showMarkers()) { GraphUtils::drawMarker(p, colorCount, x, y+(lineSpacing/2), markerSize); } p->drawText(x+legendGap, y, viewWidth_, y+lineSpacing, AlignLeft | AlignTop, it.key()); legendPos += lineSpacing; // Plot data bool firstPoint = true; p->setClipRect(leftGap_, topGap_, graphWidth_, graphHeight_); for (uint index=0; indexsetClipRect(leftGap_, topGap_, graphWidth_, graphHeight_); if ( (x >= leftGap_) && (x <= (leftGap_+graphWidth_)) ) { if (firstPoint) { p->moveTo(x,y); firstPoint = false; } else p->lineTo(x,y); } p->setClipRect(0,0,viewWidth_, viewHeight_); // Draw markers if ( ((index % markerSpace) == 0) && showMarkers() ) { GraphUtils::drawMarker(p, colorCount, x, y, markerSize); } } //for if ( showMarkers() ) { GraphUtils::drawMarker(p, colorCount, x, y, markerSize); } colorCount++; rowNo++; } //while int x = leftGap_ + graphWidth_; int y = legendPos; int w = viewWidth_ - x; int h = viewHeight_ - y; cursorLegendRect_.setRect(x, y, w, h); } //---------------------------------------------------------------------------- void GridView::drawLabels(QPainter* p) { //Draw labels QString label; label.sprintf("%3.3f", yAxisMax_); p->drawText(0, topGap_, leftGap_, graphHeight_, AlignRight | AlignTop, label); label.sprintf("%3.3f", yAxisMin_); p->drawText(0, 0, leftGap_, topGap_+graphHeight_, AlignRight | AlignBottom, label); label.sprintf("%3.3f", xAxisMin_); p->drawText(leftGap_, topGap_+graphHeight_, graphWidth_, viewHeight_, AlignLeft | AlignTop, label); label.sprintf("%3.3f", xAxisMax_); p->drawText(0, topGap_+graphHeight_, leftGap_+graphWidth_, viewHeight_, AlignRight | AlignTop, label); p->drawText(leftGap_, topGap_+graphHeight_, graphWidth_, viewHeight_ - graphHeight_ - topGap_, AlignCenter, xAxisTitle_); } //---------------------------------------------------------------------------- void GridView::drawGrid(QPainter* p) { p->setPen( DashLine ); p->setPen( lightGray ); p->setClipRect(leftGap_, topGap_, graphWidth_, graphHeight_); // Y grid TReal yScale = TReal(graphHeight_-1) / numberYSteps_; for (uint index = 1; index < numberYSteps_; index++) { p->moveTo(leftGap_, topGap_ + (int)floor(index*yScale)); p->lineTo(leftGap_ + graphWidth_, topGap_ + (int)floor(index*yScale)); } // Linear X grid TReal xScale; if (linXAxis_) { xScale = TReal(graphWidth_-1) / numberXSteps_; for (uint index = 1; index < numberXSteps_; index++) { int x = (int)floor(index*xScale); p->moveTo(leftGap_ + x, topGap_); p->lineTo(leftGap_ + x, topGap_ + graphHeight_); } } else // Log X Axis { xScale = TReal(graphWidth_-1) / (log10(xAxisMax_)-log10(xAxisMin_)); int start = (int) (floor(log10(xAxisMin_))); int stop = (int) (ceil(log10(xAxisMax_))); for (int index = start; index < stop; index++) { TReal step = pow(10.0,(double)index); for (int index2 = 1; index2 < 10; index2++) { int x = (int)(floor((log10(step*index2)-log10(xAxisMin_))*xScale)); p->moveTo(leftGap_+x,topGap_); p->lineTo(leftGap_+x,topGap_+graphHeight_-1); } //for index2 } //for Index } //if p->setClipRect(p->window()); } //----------------------------------------------------------------------------