/*! \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; }
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(); }
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() ); }
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(); }
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())); }
/*! \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; }
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; }
/*! 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 }
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; } //} }
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 }
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(); }
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; }