예제 #1
0
void ScaleDraw::drawBreak(QPainter *painter) const {
  ScaleEngine *sc_engine =
      static_cast<ScaleEngine *>(d_plot->axisScaleEngine(axis()));
  /*const QwtScaleEngine * qwtsc_engine=d_plot->axisScaleEngine(axis());
  const ScaleEngine *sc_engine =dynamic_cast<const ScaleEngine*>(qwtsc_engine);
  if(sc_engine!=NULL)
  {*/
  if (!sc_engine->hasBreak() || !sc_engine->hasBreakDecoration())
    return;

  painter->save();
  painter->setRenderHint(QPainter::Antialiasing);

  int len = majTickLength();

  QwtScaleMap scaleMap = map();
  const QwtMetricsMap metricsMap = QwtPainter::metricsMap();
  QPoint pos = this->pos();

  if (!metricsMap.isIdentity()) {
    QwtPainter::resetMetricsMap();
    pos = metricsMap.layoutToDevice(pos);

    if (orientation() == Qt::Vertical) {
      scaleMap.setPaintInterval(metricsMap.layoutToDeviceY((int)scaleMap.p1()),
                                metricsMap.layoutToDeviceY((int)scaleMap.p2()));
      len = metricsMap.layoutToDeviceX(len);
    } else {
      scaleMap.setPaintInterval(metricsMap.layoutToDeviceX((int)scaleMap.p1()),
                                metricsMap.layoutToDeviceX((int)scaleMap.p2()));
      len = metricsMap.layoutToDeviceY(len);
    }
  }

  int lval = scaleMap.transform(sc_engine->axisBreakLeft());
  int rval = scaleMap.transform(sc_engine->axisBreakRight());
  switch (alignment()) {
  case LeftScale:
    QwtPainter::drawLine(painter, pos.x(), lval, pos.x() - len, lval + len);
    QwtPainter::drawLine(painter, pos.x(), rval, pos.x() - len, rval + len);
    break;
  case RightScale:
    QwtPainter::drawLine(painter, pos.x(), lval, pos.x() + len, lval - len);
    QwtPainter::drawLine(painter, pos.x(), rval, pos.x() + len, rval - len);
    break;
  case BottomScale:
    QwtPainter::drawLine(painter, lval, pos.y(), lval - len, pos.y() + len);
    QwtPainter::drawLine(painter, rval, pos.y(), rval - len, pos.y() + len);
    break;
  case TopScale:
    QwtPainter::drawLine(painter, lval, pos.y(), lval + len, pos.y() - len);
    QwtPainter::drawLine(painter, rval, pos.y(), rval + len, pos.y() - len);
    break;
  }

  QwtPainter::setMetricsMap(metricsMap); // restore metrics map
  painter->restore();
  //}
}
예제 #2
0
void ScaleDraw::drawBreak(QPainter *painter) const
{
	ScaleEngine *sc_engine = (ScaleEngine *)d_plot->axisScaleEngine(axis());
    if (!sc_engine->hasBreak() || !sc_engine->hasBreakDecoration())
        return;

    painter->save();
    painter->setRenderHint(QPainter::Antialiasing);

	QPen pen = painter->pen();
	pen.setColor(d_plot->axisWidget(axis())->palette().color(QPalette::Active, QColorGroup::Foreground));
	painter->setPen(pen);

	int len = d_plot->majorTickLength();

    QwtScaleMap scaleMap = map();
    const QwtMetricsMap metricsMap = QwtPainter::metricsMap();
    QPoint pos = this->pos();

	if (!d_plot->isPrinting()){
		QwtPainter::resetMetricsMap();
		pos = metricsMap.layoutToDevice(pos);

		if ( orientation() == Qt::Vertical ){
			scaleMap.setPaintInterval(
				metricsMap.layoutToDeviceY((int)scaleMap.p1()),
				metricsMap.layoutToDeviceY((int)scaleMap.p2()));
			len = metricsMap.layoutToDeviceX(len);
		} else {
			scaleMap.setPaintInterval(
				metricsMap.layoutToDeviceX((int)scaleMap.p1()),
				metricsMap.layoutToDeviceX((int)scaleMap.p2()));
			len = metricsMap.layoutToDeviceY(len);
		}
	}

	int lval = scaleMap.transform(sc_engine->axisBreakLeft());
	int rval = scaleMap.transform(sc_engine->axisBreakRight());
	switch(alignment()){
		case LeftScale:
		case RightScale:
			QwtPainter::drawLine(painter, pos.x() + len, lval - len, pos.x() - len, lval + len);
			QwtPainter::drawLine(painter, pos.x() + len, rval - len, pos.x() - len, rval + len);
		break;
		case TopScale:
		case BottomScale:
			QwtPainter::drawLine(painter, lval + len, pos.y() - len, lval - len, pos.y() + len);
			QwtPainter::drawLine(painter, rval + len, pos.y() - len, rval - len, pos.y() + len);
		break;
	}

	if (!d_plot->isPrinting())
		QwtPainter::setMetricsMap(metricsMap); // restore metrics map
	painter->restore();
}
예제 #3
0
static void qwtTransformMaps( const QTransform &tr,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    QwtScaleMap &xxMap, QwtScaleMap &yyMap )
{
    const QPointF p1 = tr.map( QPointF( xMap.p1(), yMap.p1() ) );
    const QPointF p2 = tr.map( QPointF( xMap.p2(), yMap.p2() ) );

    xxMap = xMap;
    xxMap.setPaintInterval( p1.x(), p2.x() );

    yyMap = yMap;
    yyMap.setPaintInterval( p1.y(), p2.y() );
}
예제 #4
0
QDebug operator<<( QDebug debug, const QwtScaleMap &map )
{
    debug.nospace() << "QwtScaleMap("
        << static_cast<int>( map.transformation()->type() )
        << ", s:" << map.s1() << "->" << map.s2()
        << ", p:" << map.p1() << "->" << map.p2()
        << ")";

    return debug.space();
}
예제 #5
0
void PeakPickerTool::draw(QPainter *p, const QwtScaleMap &xMap,
                          const QwtScaleMap &yMap, const QRect &) const {
  try {
    MantidQt::MantidWidgets::PropertyHandler *h =
        m_fitPropertyBrowser->getHandler();
    if (!h)
      return;
    QList<MantidQt::MantidWidgets::PropertyHandler *> peaks = h->getPeakList();
    foreach (MantidQt::MantidWidgets::PropertyHandler *peak, peaks) {
      double c = peak->centre();
      if (c >= xMap.s1() && c <= xMap.s2()) {
        int ic = xMap.transform(c);
        if (peak ==
            m_fitPropertyBrowser->currentHandler()) { // draw current peak
          double width = peak->fwhm();
          QPen pen;
          pen.setColor(QColor(255, 0, 0));
          pen.setStyle(Qt::DashLine);
          p->setPen(pen);
          int x1 = xMap.transform(c - width / 2);
          int x2 = xMap.transform(c + width / 2);
          QwtPainter::drawLine(p, x1, int(yMap.p1()), x1, int(yMap.p2()));
          QwtPainter::drawLine(p, x2, int(yMap.p1()), x2, int(yMap.p2()));

          pen.setStyle(Qt::SolidLine);
          p->setPen(pen);
          int ih = yMap.transform(peak->height() + peak->base());
          int ib = yMap.transform(peak->base());
          QwtPainter::drawLine(p, ic, ib, ic, ih);
          QwtPainter::drawLine(p, x1, ib, x2, ib);
        } else {
          p->setPen(QPen(QColor(200, 200, 200)));
          QwtPainter::drawLine(p, ic, int(yMap.p1()), ic, int(yMap.p2()));
        }
      }
    }
  } catch (...) {
    // Do nothing
  }
  QPen pen;
  pen.setColor(QColor(0, 0, 255));
  pen.setStyle(Qt::DashLine);
  p->setPen(pen);
  int x1 = xMap.transform(xMin());
  int x2 = xMap.transform(xMax());
  QwtPainter::drawLine(p, x1, int(yMap.p1()), x1, int(yMap.p2()));
  QwtPainter::drawLine(p, x2, int(yMap.p1()), x2, int(yMap.p2()));

  pen.setColor(QColor(0, 0, 255));
  pen.setStyle(Qt::SolidLine);
  p->setPen(pen);
  QwtPainter::drawLine(p, x1, int(yMap.p1()), x1 + 3, int(yMap.p1()));
  QwtPainter::drawLine(p, x1, int(yMap.p2()), x1 + 3, int(yMap.p2()));

  QwtPainter::drawLine(p, x2, int(yMap.p1()), x2 - 3, int(yMap.p1()));
  QwtPainter::drawLine(p, x2, int(yMap.p2()), x2 - 3, int(yMap.p2()));
}
예제 #6
0
/// Draw curve in Sticks style
void FunctionCurve::drawSticks(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap,
  const QRect &canvasRect) const
{
  const double start = xMap.s1();
  const double end = xMap.s2();

  const size_t n = m_x->size();
  // find first point to draw which is 0 or the one before first visible
  size_t istart = 0;
  for(; istart < n; ++istart)
  {
    const double& x = (*m_x)[istart];
    if ( x < start ) continue;
    if ( x > end ) break;
    if ( istart > 0 ) --istart;
    break;
  }
  if ( istart >= n ) return;
  size_t iend = n;

  bool doDrawSymbols = m_symbol->style() != QwtSymbol::NoSymbol;
  if ( doDrawSymbols && m_pointCoords.size() != n )
  {
    m_pointCoords.resize(n);
  }

  // draw the points
  int y1 = yMap.p1();
  for(size_t i = istart; i < n; ++i)
  {
    const double& x = (*m_x)[i];
    if ( x > end )
    {
      iend = i;
      break;
    }
    int x2 = xMap.transform(x);
    int y2 = yMap.transform(m_y.getCalculated(i));
    painter->drawLine(x2,y1,x2,y2);
    if ( doDrawSymbols )
    {
      m_pointCoords[i] = QPoint(x2,y2);
    }
  }

  // draw the symbols
  if ( doDrawSymbols )
  {
    drawSymbols(painter,istart,iend);
  }
}
예제 #7
0
QRectF
Annotations::boundingRect( double x, double y, const QwtText& label, Qt::Alignment align ) const
{
	QSizeF sz = label.textSize();
    
	const QwtScaleMap xMap = plot_.canvasMap( QwtPlot::xBottom );
	const QwtScaleMap yMap = plot_.canvasMap( QwtPlot::yLeft );
#if 0
	double p1 = xMap.p1(); // device left
	double p2 = xMap.p2(); // device right
	double s1 = xMap.s1(); // axis left
	double s2 = xMap.s2(); // axis right
#endif	
	QPointF pt( QwtScaleMap::transform( xMap, yMap, QPointF( x, y ) ) );
	QRectF rc( QwtScaleMap::transform( xMap, yMap, QRectF( pt, sz ) ) );

    adjust( rc, align );

    return rc;
}
예제 #8
0
/*!
   Draw a tick

   \param painter Painter
   \param value Value of the tick
   \param len Lenght of the tick

   \sa drawBackbone(), drawLabel()
*/
void QwtScaleDraw::drawTick(QPainter *painter, double value, int len) const
{
    if ( len <= 0 )
        return;

    int pw2 = qwtMin((int)painter->pen().width(), len) / 2;
    
    QwtScaleMap scaleMap = map();
    const QwtMetricsMap metricsMap = QwtPainter::metricsMap();
    QPoint pos = d_data->pos;

    if ( !metricsMap.isIdentity() )
    {
        /*
           The perfect position of the ticks is important.
           To avoid rounding errors we have to use 
           device coordinates.
         */
        QwtPainter::resetMetricsMap();

        pos = metricsMap.layoutToDevice(pos);
    
        if ( orientation() == Qt::Vertical )
        {
            scaleMap.setPaintInterval(
                metricsMap.layoutToDeviceY((int)scaleMap.p1()),
                metricsMap.layoutToDeviceY((int)scaleMap.p2())
            );
            len = metricsMap.layoutToDeviceX(len);
        }
        else
        {
            scaleMap.setPaintInterval(
                metricsMap.layoutToDeviceX((int)scaleMap.p1()),
                metricsMap.layoutToDeviceX((int)scaleMap.p2())
            );
            len = metricsMap.layoutToDeviceY(len);
        }
    }

    const int tval = scaleMap.transform(value);

    switch(alignment())
    {
        case LeftScale:
        {
#if QT_VERSION < 0x040000
            QwtPainter::drawLine(painter, pos.x() + pw2, tval,
                pos.x() - len - 2 * pw2, tval);
#else
            QwtPainter::drawLine(painter, pos.x() - pw2, tval,
                pos.x() - len, tval);
#endif
            break;
        }

        case RightScale:
        {
#if QT_VERSION < 0x040000
            QwtPainter::drawLine(painter, pos.x(), tval,
                pos.x() + len + pw2, tval);
#else
            QwtPainter::drawLine(painter, pos.x() + pw2, tval,
                pos.x() + len, tval);
#endif
            break;
        }
    
        case BottomScale:
        {
#if QT_VERSION < 0x040000
            QwtPainter::drawLine(painter, tval, pos.y(),
                tval, pos.y() + len + 2 * pw2);
#else
            QwtPainter::drawLine(painter, tval, pos.y() + pw2,
                tval, pos.y() + len);
#endif
            break;
        }

        case TopScale:
        {
#if QT_VERSION < 0x040000
            QwtPainter::drawLine(painter, tval, pos.y() + pw2,
                tval, pos.y() - len - 2 * pw2);
#else
            QwtPainter::drawLine(painter, tval, pos.y() - pw2,
                tval, pos.y() - len);
#endif
            break;
        }
    }
    QwtPainter::setMetricsMap(metricsMap); // restore metrics map
}
예제 #9
0
void ScaleDraw::drawBackbone(QPainter *painter) const
{
    ScaleEngine *sc_engine = (ScaleEngine *)d_plot->axisScaleEngine(axis());
	/*QwtScaleEngine *qwtsc_engine=d_plot->axisScaleEngine(axis());
	ScaleEngine *sc_engine =dynamic_cast<ScaleEngine*>(qwtsc_engine);
	if(sc_engine!=NULL)
	{*/
		if (!sc_engine->hasBreak()){
			const int len = length();
			const int bw = painter->pen().width();
			const int bw2 = bw / 2;
			QPoint pos = this->pos();
			switch(alignment()){
			case LeftScale:
				QwtPainter::drawLine(painter, pos.x() - bw2,
					pos.y(), pos.x() - bw2, pos.y() + len );
				break;
			case RightScale:
				QwtPainter::drawLine(painter, pos.x() + bw2,
					pos.y(), pos.x() + bw2, pos.y() + len);
				break;
			case TopScale:
				QwtPainter::drawLine(painter, pos.x(), pos.y() - bw2,
					pos.x() + len, pos.y() - bw2);
				break;
			case BottomScale:
				QwtPainter::drawLine(painter, pos.x(), pos.y() + bw2,
					pos.x() + len, pos.y() + bw2);
				break;
			}
			return;
		}

		QwtScaleMap scaleMap = map();
		const QwtMetricsMap metricsMap = QwtPainter::metricsMap();
		QPoint pos = this->pos();

		if ( !metricsMap.isIdentity() ){
			QwtPainter::resetMetricsMap();
			pos = metricsMap.layoutToDevice(pos);

			if ( orientation() == Qt::Vertical ){
				scaleMap.setPaintInterval(
					metricsMap.layoutToDeviceY((int)scaleMap.p1()),
					metricsMap.layoutToDeviceY((int)scaleMap.p2()));
			} else {
				scaleMap.setPaintInterval(
					metricsMap.layoutToDeviceX((int)scaleMap.p1()),
					metricsMap.layoutToDeviceX((int)scaleMap.p2()));
			}
		}

		const int start = scaleMap.transform(sc_engine->axisBreakLeft());
		const int end = scaleMap.transform(sc_engine->axisBreakRight());
		int lb = start, rb = end;
		if (sc_engine->testAttribute(QwtScaleEngine::Inverted)){
			lb = end;
			rb = start;
		}

		const int bw = painter->pen().width();
		const int bw2 = bw / 2;
		const int len = length() - 1;
		int aux;
		switch(alignment())
		{
		case LeftScale:
			aux = pos.x() - bw2;
			QwtPainter::drawLine(painter, aux, pos.y(), aux, rb);
			QwtPainter::drawLine(painter, aux, lb + bw, aux, pos.y() + len);
			break;
		case RightScale:
			aux = pos.x() + bw2;
			QwtPainter::drawLine(painter, aux, pos.y(), aux, rb - bw - 1);
			QwtPainter::drawLine(painter, aux, lb - bw2, aux, pos.y() + len);
			break;
		case TopScale:
			aux = pos.y() - bw2;
			QwtPainter::drawLine(painter, pos.x(), aux, lb - bw2, aux);
			QwtPainter::drawLine(painter, rb + bw, aux, pos.x() + len, aux);
			break;
		case BottomScale:
			aux = pos.y() + bw2;
			QwtPainter::drawLine(painter, pos.x(), aux, lb - bw, aux);
			QwtPainter::drawLine(painter, rb, aux, pos.x() + len, aux);
			break;
		}
	//}
}
예제 #10
0
/*!
   Update the axis scale draw geometries

   \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI
   \param radialMap Maps radius values into painter coordinates.
   \param pole Position of the pole in painter coordinates
   \param radius Radius of the complete plot area in painter coordinates

   \sa updateScaleDiv()
*/
void QwtPolarGrid::updateScaleDraws(
  const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
  const QwtDoublePoint &pole, double radius ) const
{
  const QPoint p = pole.toPoint();

  const QwtDoubleInterval interval =
    d_data->gridData[QwtPolar::ScaleRadius].scaleDiv.interval();

  const int min = radialMap.transform( interval.minValue() );
  const int max = radialMap.transform( interval.maxValue() );
  const int l = max - min;

  for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
  {
    AxisData &axis = d_data->axisData[axisId];

    if ( axisId == QwtPolar::AxisAzimuth )
    {
      QwtRoundScaleDraw *scaleDraw = ( QwtRoundScaleDraw * )axis.scaleDraw;

      scaleDraw->setRadius( qRound( radius ) );
      scaleDraw->moveCenter( p );

      double from = ::fmod( 90.0 - azimuthMap.p1() * 180.0 / M_PI, 360.0 );
      if ( from < 0.0 )
        from += 360.0;

      scaleDraw->setAngleRange( from, from - 360.0 );
      scaleDraw->setTransformation( azimuthMap.transformation()->copy() );
    }
    else
    {
      QwtScaleDraw *scaleDraw = ( QwtScaleDraw * )axis.scaleDraw;
      switch ( axisId )
      {
        case QwtPolar::AxisLeft:
        {
          scaleDraw->move( p.x() - min, p.y() );
          scaleDraw->setLength( -l );
          break;
        }
        case QwtPolar::AxisRight:
        {
          scaleDraw->move( p.x() + min, p.y() );
          scaleDraw->setLength( l );
          break;
        }
        case QwtPolar::AxisTop:
        {
          scaleDraw->move( p.x(), p.y() - max );
          scaleDraw->setLength( l );
          break;
        }
        case QwtPolar::AxisBottom:
        {
          scaleDraw->move( p.x(), p.y() + max );
          scaleDraw->setLength( -l );
          break;
        }
      }
      scaleDraw->setTransformation( radialMap.transformation()->copy() );
    }
  }
}
예제 #11
0
void ScaleDraw::drawInwardTick(QPainter *painter, double value, int len) const
{
	ScaleEngine *sc_engine = (ScaleEngine *)d_plot->axisScaleEngine(axis());
	if (sc_engine->hasBreak() && (sc_engine->axisBreakLeft() <= value && sc_engine->axisBreakRight() >= value))
		return;

	int pw2 = qwtMin((int)painter->pen().width(), len) / 2;

	QwtScaleMap scaleMap = map();
	const QwtMetricsMap metricsMap = QwtPainter::metricsMap();
	QPoint pos = this->pos();

	int majLen = tickLength(QwtScaleDiv::MajorTick);

	if ( !metricsMap.isIdentity() ){
		/*
		   The perfect position of the ticks is important.
		   To avoid rounding errors we have to use
		   device coordinates.
		 */
		QwtPainter::resetMetricsMap();

		pos = metricsMap.layoutToDevice(pos);

		if ( orientation() == Qt::Vertical ){
			scaleMap.setPaintInterval(
				metricsMap.layoutToDeviceY((int)scaleMap.p1()),
				metricsMap.layoutToDeviceY((int)scaleMap.p2())
			);
			len = metricsMap.layoutToDeviceX(len);
			majLen = metricsMap.layoutToDeviceX(majLen);
		} else {
			scaleMap.setPaintInterval(
				metricsMap.layoutToDeviceX((int)scaleMap.p1()),
				metricsMap.layoutToDeviceX((int)scaleMap.p2())
			);
			len = metricsMap.layoutToDeviceY(len);
			majLen = metricsMap.layoutToDeviceY(majLen);
		}
	}

	const int clw = d_plot->canvasLineWidth();
	const int tval = scaleMap.transform(value);

	bool draw = false;
	if ( orientation() == Qt::Vertical ){
		int low = (int)scaleMap.p2() + majLen;
		int high = (int)scaleMap.p1() - majLen;
		if ((tval > low && tval < high) ||
			(tval > high && !d_plot->axisEnabled (QwtPlot::xBottom) && !clw) ||
			(tval < low && !d_plot->axisEnabled(QwtPlot::xTop) && !clw)) draw = true;
	} else {
		int low = (int)scaleMap.p1() + majLen;
		int high = (int)scaleMap.p2() - majLen;
		if ((tval > low && tval < high) ||
			(tval > high && !d_plot->axisEnabled(QwtPlot::yRight) && !clw) ||
			(tval < low && !d_plot->axisEnabled(QwtPlot::yLeft) && !clw)) draw = true;
	}

	if (draw){
		switch(alignment()){
			case LeftScale:
			{
				QwtPainter::drawLine(painter, pos.x() + pw2, tval, pos.x() + len, tval);
				break;
			}
			case RightScale:
			{
				QwtPainter::drawLine(painter, pos.x() - pw2, tval, pos.x() - len, tval);
				break;
			}
			case BottomScale:
			{
				QwtPainter::drawLine(painter, tval, pos.y() - pw2, tval, pos.y() - len);
				break;
			}
			case TopScale:
			{
				QwtPainter::drawLine(painter, tval, pos.y() + pw2, tval, pos.y() + len);
				break;
			}
		}
	}
	QwtPainter::setMetricsMap(metricsMap); // restore metrics map
}
예제 #12
0
/*!
  \brief Render a sub-rectangle of an image 

  renderTile() is called by renderImage() to render different parts
  of the image by concurrent threads.

  \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI
  \param radialMap Maps radius values into painter coordinates.
  \param pole Position of the pole in painter coordinates
  \param imagePos Top/left position of the image in painter coordinates
  \param tile Sub-rectangle of the tile in painter coordinates
  \param image Image to be rendered

   \sa setRenderThreadCount()
   \note renderTile needs to be reentrant
*/
void QwtPolarSpectrogram::renderTile(
    const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
    const QPointF &pole, const QPoint &imagePos,
    const QRect &tile, QImage *image ) const
{
    const QwtInterval intensityRange = d_data->data->interval( Qt::ZAxis );
    if ( !intensityRange.isValid() )
        return;

    const bool doFastAtan = testPaintAttribute( ApproximatedAtan );

    const int y0 = imagePos.y();
    const int y1 = tile.top();
    const int y2 = tile.bottom();

    const int x0 = imagePos.x();
    const int x1 = tile.left();
    const int x2 = tile.right();

    if ( d_data->colorMap->format() == QwtColorMap::RGB )
    {
        for ( int y = y1; y <= y2; y++ )
        {
            const double dy = pole.y() - y;
            const double dy2 = qwtSqr( dy );

            QRgb *line = reinterpret_cast<QRgb *>( image->scanLine( y - y0 ) );
            line += x1 - x0;

            for ( int x = x1; x <= x2; x++ )
            {
                const double dx = x - pole.x();

                double a =  doFastAtan ? qwtFastAtan2( dy, dx ) : qAtan2( dy, dx );
                if ( a < 0.0 )
                    a += 2 * M_PI;
                if ( a < azimuthMap.p1() )
                    a += 2 * M_PI;

                const double r = qSqrt( qwtSqr( dx ) + dy2 );

                const double azimuth = azimuthMap.invTransform( a );
                const double radius = radialMap.invTransform( r );

                const double value = d_data->data->value( azimuth, radius );
                *line++ = d_data->colorMap->rgb( intensityRange, value );
            }
        }
    }
    else if ( d_data->colorMap->format() == QwtColorMap::Indexed )
    {
        for ( int y = y1; y <= y2; y++ )
        {
            const double dy = pole.y() - y;
            const double dy2 = qwtSqr( dy );

            unsigned char *line = image->scanLine( y - y0 );
            line += x1 - x0;
            for ( int x = x1; x <= x2; x++ )
            {
                const double dx = x - pole.x();

                double a =  doFastAtan ? qwtFastAtan2( dy, dx ) : qAtan2( dy, dx );
                if ( a < 0.0 )
                    a += 2 * M_PI;
                if ( a < azimuthMap.p1() )
                    a += 2 * M_PI;

                const double r = qSqrt( qwtSqr( dx ) + dy2 );

                const double azimuth = azimuthMap.invTransform( a );
                const double radius = radialMap.invTransform( r );

                const double value = d_data->data->value( azimuth, radius );
                *line++ = d_data->colorMap->colorIndex( intensityRange, value );
            }
        }
    }
}
예제 #13
0
void QwtPieCurve::drawDisk(QPainter *painter, const QwtScaleMap &xMap,
                           const QwtScaleMap &yMap) const {
  const double x_width = fabs(xMap.p1() - xMap.p2());
  const double x_center =
      (xMap.p1() + xMap.p2()) * 0.5 + d_horizontal_offset * 0.01 * x_width;
  const double y_center = (yMap.p1() + yMap.p2()) * 0.5;
  const double ray_x =
      d_pie_ray * 0.005 * qMin(x_width, fabs(yMap.p1() - yMap.p2()));
  const double view_angle_rad = d_view_angle * M_PI / 180.0;
  const double ray_y = ray_x * sin(view_angle_rad);
  const double thick = 0.01 * d_thickness * ray_x * cos(view_angle_rad);

  QRectF pieRect;
  pieRect.setX(x_center - ray_x);
  pieRect.setY(y_center - ray_y);
  pieRect.setWidth(2 * ray_x);
  pieRect.setHeight(2 * ray_y);

  QRectF pieRect2 = pieRect;
  pieRect2.translate(0, thick);

  painter->save();

  painter->setPen(QwtPlotCurve::pen());
  painter->setBrush(QBrush(color(0), QwtPlotCurve::brush().style()));

  QPointF start(x_center + ray_x, y_center);
  QPainterPath path(start);
  path.lineTo(start.x(), start.y() + thick);
  path.arcTo(pieRect2, 0, -180.0);
  QPointF aux = path.currentPosition();
  path.lineTo(aux.x(), aux.y() - thick);
  path.arcTo(pieRect, -180.0, 180.0);
  painter->drawPath(path);

  painter->drawEllipse(pieRect);

  if (d_texts_list.size() > 0) {
    PieLabel *l = d_texts_list[0];
    if (l) {
      QString s;
      if (d_auto_labeling) {
        if (d_categories)
          s += QString::number(d_table_rows[0]) + "\n";

        if (d_values && d_percentages)
          s += (static_cast<Plot *>(plot()))->locale().toString(y(0), 'g', 4) +
               " (100%)";
        else if (d_values)
          s += (static_cast<Plot *>(plot()))->locale().toString(y(0), 'g', 4);
        else if (d_percentages)
          s += "100%";
        l->setText(s);
        if (l->isHidden())
          l->show();
      } else
        l->setText(l->customText());

      if (d_fixed_labels_pos) {
        double a_deg = d_start_azimuth + 180.0;
        if (a_deg > 360)
          a_deg -= 360;
        double a_rad = a_deg * M_PI / 180.0;
        double rx = ray_x * (1 + 0.01 * d_edge_dist);
        const double x = x_center + rx * cos(a_rad);
        double ry = ray_y * (1 + 0.01 * d_edge_dist);
        double y = y_center + ry * sin(a_rad);
        if (a_deg > 0 && a_deg < 180)
          y += thick;

        double dx = xMap.invTransform(x - l->width() / 2);
        double dy = yMap.invTransform(y - l->height() / 2);
        l->setOriginCoord(dx, dy);
      }
    }
  }
  painter->restore();
}
예제 #14
0
void QwtPieCurve::drawSlices(QPainter *painter, const QwtScaleMap &xMap,
                             const QwtScaleMap &yMap, int from, int to) const {
  const double x_width = fabs(xMap.p1() - xMap.p2());
  const double x_center =
      (xMap.p1() + xMap.p2()) * 0.5 + d_horizontal_offset * 0.01 * x_width;
  const double y_center = (yMap.p1() + yMap.p2()) * 0.5;
  const double ray_x =
      d_pie_ray * 0.005 * qMin(x_width, fabs(yMap.p1() - yMap.p2()));
  const double view_angle_rad = d_view_angle * M_PI / 180.0;
  const double ray_y = ray_x * sin(view_angle_rad);
  const double thick = 0.01 * d_thickness * ray_x * cos(view_angle_rad);

  QRectF pieRect;
  pieRect.setX(x_center - ray_x);
  pieRect.setY(y_center - ray_y);
  pieRect.setWidth(2 * ray_x);
  pieRect.setHeight(2 * ray_y);

  QRectF pieRect2 = pieRect;
  pieRect2.translate(0, thick);

  double sum = 0.0;
  for (int i = from; i <= to; i++)
    sum += y(i);

  const int sign = d_counter_clockwise ? 1 : -1;

  const int size = dataSize();
  double *start_angle = new double[size];
  double *end_angle = new double[size];
  double aux_angle = d_start_azimuth;
  for (int i = from; i <= to; i++) {
    double a = -sign * y(i) / sum * 360.0;
    start_angle[i] = aux_angle;

    double end = aux_angle + a;
    if (end >= 360)
      end -= 360;
    else if (end < 0)
      end += 360;

    end_angle[i] = end;
    aux_angle = end;
  }

  int angle = (int)(5760 * d_start_azimuth / 360.0);
  if (d_counter_clockwise)
    angle = (int)(5760 * (1 - d_start_azimuth / 360.0));

  painter->save();

  QLocale locale = (static_cast<Plot *>(plot()))->locale();
  for (int i = from; i <= to; i++) {
    const double yi = y(i);
    const double q = yi / sum;
    const int value = (int)(q * 5760);

    painter->setPen(QwtPlotCurve::pen());
    painter->setBrush(QBrush(color(i), QwtPlotCurve::brush().style()));

    double deg = q * 360;
    double start_3D_view_angle = start_angle[i];
    double end_3D_view_angle = end_angle[i];
    if (d_counter_clockwise) {
      start_3D_view_angle = end_angle[i];
      end_3D_view_angle = start_angle[i];
    }

    bool draw3D = false;
    if (deg <= 180 && start_3D_view_angle >= 0 && start_3D_view_angle < 180) {
      if ((end_3D_view_angle > 180 &&
           end_3D_view_angle > start_3D_view_angle)) {
        deg = 180 - start_3D_view_angle;
        end_3D_view_angle = 180.0;
      }
      draw3D = true;
    } else if (start_3D_view_angle >= 180 &&
               end_3D_view_angle < start_3D_view_angle) {
      if (end_3D_view_angle > 180)
        end_3D_view_angle = 180;
      deg = end_3D_view_angle;
      start_3D_view_angle = 0;
      draw3D = true;
    } else if (deg > 180 && start_3D_view_angle >= 180) {
      deg = 180;
      end_3D_view_angle = 180;
      start_3D_view_angle = 0;
      draw3D = true;
    }

    if (draw3D) {
      double rad = start_3D_view_angle / 180.0 * M_PI;
      QPointF start(x_center + ray_x * cos(rad), y_center + ray_y * sin(rad));
      QPainterPath path(start);
      path.lineTo(start.x(), start.y() + thick);
      path.arcTo(pieRect2, -start_3D_view_angle, -deg);
      QPointF aux = path.currentPosition();
      path.lineTo(aux.x(), aux.y() - thick);
      path.arcTo(pieRect, -end_3D_view_angle, deg);
      painter->drawPath(path);
    } else {
      if (start_3D_view_angle >= 0 && start_3D_view_angle < 180) {
        if (end_3D_view_angle > 180)
          end_3D_view_angle = 0;

        double rad = start_3D_view_angle / 180.0 * M_PI;
        QPointF start(x_center + ray_x * cos(rad), y_center + ray_y * sin(rad));
        QPainterPath path(start);
        path.lineTo(start.x(), start.y() + thick);

        deg = 180 - start_3D_view_angle;
        path.arcTo(pieRect2, -start_3D_view_angle, -deg);
        QPointF aux = path.currentPosition();
        path.lineTo(aux.x(), aux.y() - thick);
        path.arcTo(pieRect, -180, deg);
        painter->drawPath(path);

        path.moveTo(QPointF(x_center + ray_x, y_center));
        aux = path.currentPosition();
        path.lineTo(aux.x(), aux.y() + thick);
        path.arcTo(pieRect2, 0, -end_3D_view_angle);
        aux = path.currentPosition();
        path.lineTo(aux.x(), aux.y() - thick);
        path.arcTo(pieRect, -end_3D_view_angle, end_3D_view_angle);
        painter->drawPath(path);
      }
    }

    painter->drawPie(pieRect, sign * angle, sign * value);
    angle += value;

    if (i >= d_texts_list.size())
      continue;

    PieLabel *l = d_texts_list[i];
    if (l) {
      QString s;
      if (d_auto_labeling) {
        if (d_categories)
          s += QString::number(d_table_rows[i]) + "\n";
        if (d_values && d_percentages)
          s += locale.toString(yi, 'g', 4) + " (" +
               locale.toString(q * 100, 'g', 4) + "%)";
        else if (d_values)
          s += locale.toString(yi, 'g', 4);
        else if (d_percentages)
          s += locale.toString(q * 100, 'g', 4) + "%";
        l->setText(s);
        if (l->isHidden())
          l->show();
      } else
        l->setText(l->customText());

      if (d_fixed_labels_pos) {
        double a_deg = start_angle[i] - sign * q * 180.0;
        if (a_deg > 360)
          a_deg -= 360.0;
        double a_rad = a_deg * M_PI / 180.0;

        double rx = ray_x * (1 + 0.01 * d_edge_dist);
        const double x = x_center + rx * cos(a_rad);

        double ry = ray_y * (1 + 0.01 * d_edge_dist);
        double y = y_center + ry * sin(a_rad);
        if (a_deg > 0 && a_deg < 180)
          y += thick;

        double dx = xMap.invTransform(x - l->width() / 2);
        double dy = yMap.invTransform(y - l->height() / 2);
        l->setOriginCoord(dx, dy);
      }
    }
  }
  painter->restore();
  delete[] start_angle;
  delete[] end_angle;
}