示例#1
0
/*!
   \brief Calculate the bounding rect of the plot area

   The plot area depends on the zoom parameters.

   \param canvasRect Rectangle of the canvas
   \return Rectangle for displaying 100% of the plot
*/
QRectF QwtPolarPlot::plotRect( const QRectF &canvasRect ) const
{
    const QwtScaleDiv *sd = scaleDiv( QwtPolar::Radius );
    const QwtScaleEngine *se = scaleEngine( QwtPolar::Radius );

    const int margin = plotMarginHint();
    const QRectF cr = canvasRect;
    const int radius = qMin( cr.width(), cr.height() ) / 2 - margin;

    QwtScaleMap map;
    map.setTransformation( se->transformation() );
    map.setPaintInterval( 0.0, radius / d_data->zoomFactor );
    map.setScaleInterval( sd->lowerBound(), sd->upperBound() );

    double v = map.s1();
    if ( map.s1() <= map.s2() )
        v += d_data->zoomPos.radius();
    else
        v -= d_data->zoomPos.radius();
    v = map.transform( v );

    const QPointF off =
        QwtPointPolar( d_data->zoomPos.azimuth(), v ).toPoint();

    QPointF center( cr.center().x(), cr.top() + margin + radius );
    center -= QPointF( off.x(), -off.y() );

    QRectF rect( 0, 0, 2 * map.p2(), 2 * map.p2() );
    rect.moveCenter( center );

    return rect;
}
示例#2
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();
  //}
}
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();
}
示例#4
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() );
}
示例#5
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();
}
示例#6
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()));
}
示例#7
0
/*!
   \brief Calculate the bounding rect of the plot area

   The plot area depends on the zoom parameters.

   \param canvasRect Rectangle of the canvas
   \return Rectangle for displaying 100% of the plot
*/
QwtDoubleRect QwtPolarPlot::plotRect( const QRect &canvasRect ) const
{
  const QwtScaleDiv *sd = scaleDiv( QwtPolar::Radius );
  const QwtScaleEngine *se = scaleEngine( QwtPolar::Radius );

  const int margin = plotMarginHint();
  const QRect cr = canvasRect;
  const int radius = qwtMin( cr.width(), cr.height() ) / 2 - margin;

  QwtScaleMap map;
  map.setTransformation( se->transformation() );
  map.setPaintXInterval( 0.0, radius / d_data->zoomFactor );
#if QWT_VERSION < 0x050200
  map.setScaleInterval( sd->lBound(), sd->hBound() );
#else
  map.setScaleInterval( sd->lowerBound(), sd->upperBound() );
#endif

  double v = map.s1();
  if ( map.s1() <= map.s2() )
    v += d_data->zoomPos.radius();
  else
    v -= d_data->zoomPos.radius();
  v = map.xTransform( v );

  const QwtDoublePoint off =
    QwtPolarPoint( d_data->zoomPos.azimuth(), v ).toPoint();

  QwtDoublePoint center( cr.center().x(), cr.top() + margin + radius );
  center -= QwtDoublePoint( off.x(), -off.y() );

  QwtDoubleRect rect( 0, 0, 2 * map.p2(), 2 * map.p2() );
  rect.moveCenter( center );

  return rect;
}
示例#8
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;
}
示例#9
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
}
示例#10
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;
		}
	//}
}
示例#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
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();
}
示例#13
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;
}