VirtualBox

Ignore:
Timestamp:
Sep 13, 2019 8:07:18 AM (5 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9510: Changing the doughnut chart's style for the CPU load metric.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/information/UIInformationRuntime.cpp

    r80554 r80766  
    154154    Q_OBJECT;
    155155
    156 signals:
    157 
    158 
    159 
    160156public:
    161157
     
    194190     * @{ */
    195191       void drawXAxisLabels(QPainter &painter, int iXSubAxisCount);
    196        void drawPieChart(QPainter &painter, quint64 iMaximum, int iDataIndex, const QRectF &chartRect, int iAlpha);
     192       void drawPieChart(QPainter &painter, quint64 iMaximum, int iDataIndex, const QRectF &chartRect, bool fWithBorder = true);
    197193       void drawCombinedPieCharts(QPainter &painter, quint64 iMaximum);
    198194       void drawDoughnutChart(QPainter &painter, quint64 iMaximum, int iDataIndex,
    199                               const QRectF &chartRect, const QRectF &innerRect, int iAlpha);
     195                              const QRectF &chartRect, const QRectF &innerRect);
     196       void drawCombinedDoughnutChart(QPainter &painter, quint64 iMaximum,
     197                                      const QRectF &chartRect, const QRectF &innerRect);
    200198
    201199       /** Drawing an overlay rectangle over the charts to indicate that they are disabled. */
    202200       void drawDisabledChartRectangle(QPainter &painter);
     201       /* Returns a half translucent complete arc. */
     202       QPainterPath wholeArc(const QRectF &rectangle);
     203       QPainterPath doughnutSlice(const QRectF &outerRectangle, const QRectF &innerRectangle,
     204                                  float fStartAngle, float fSweepAngle);
     205       QConicalGradient conicalGradientForDataSeries(const QRectF &rectangle, int iDataIndex);
    203206    /** @} */
    204207
     
    210213    int m_iMarginTop;
    211214    int m_iMarginBottom;
     215    int m_iOverlayAlpha;
    212216    QRect m_lineChartRect;
    213217    int m_iPieChartRadius;
     
    519523    , m_pMetric(pMetric)
    520524    , m_size(QSize(50, 50))
     525    , m_iOverlayAlpha(80)
    521526    , m_fWithPieChart(false)
    522527    , m_fUseGradientLineColor(false)
     
    526531            this, &UIChart::sltCreateContextMenu);
    527532
    528     m_dataSeriesColor[0] = QColor(Qt::red);
    529     m_dataSeriesColor[1] = QColor(Qt::blue);
     533    m_dataSeriesColor[0] = QColor(200, 0, 0, 255);
     534    m_dataSeriesColor[1] = QColor(0, 0, 200, 255);
    530535
    531536    m_iMarginLeft = 1 * qApp->QApplication::style()->pixelMetric(QStyle::PM_LayoutTopMargin);
     
    751756}
    752757
    753 void UIChart::drawPieChart(QPainter &painter, quint64 iMaximum, int iDataIndex, const QRectF &chartRect, int iAlpha)
     758void UIChart::drawPieChart(QPainter &painter, quint64 iMaximum, int iDataIndex,
     759                           const QRectF &chartRect, bool fWithBorder /* = false */)
    754760{
    755761    if (!m_pMetric)
     
    761767
    762768    /* Draw a whole non-filled circle: */
    763     painter.setPen(QPen(QColor(100, 100, 100, iAlpha), 1));
    764     painter.drawArc(chartRect, 0, 3600 * 16);
     769    if (fWithBorder)
     770    {
     771        painter.setPen(QPen(QColor(100, 100, 100, m_iOverlayAlpha), 1));
     772        painter.drawArc(chartRect, 0, 3600 * 16);
     773        painter.setPen(Qt::NoPen);
     774    }
     775
     776   /* Draw a white filled circle and that the arc for data: */
     777    QPainterPath background = wholeArc(chartRect);
    765778    painter.setPen(Qt::NoPen);
    766     /* Prepare the gradient for the pie chart: */
    767     QConicalGradient pieGradient;
    768     pieGradient.setCenter(chartRect.center());
    769     pieGradient.setAngle(90);
    770     pieGradient.setColorAt(0, QColor(0, 0, 0, iAlpha));
    771     QColor pieColor(m_dataSeriesColor[iDataIndex]);
    772     pieColor.setAlpha(iAlpha);
    773     pieGradient.setColorAt(1, pieColor);
     779    painter.setBrush(QColor(255, 255, 255, m_iOverlayAlpha));
     780    painter.drawPath(background);
    774781
    775782    float fAngle = 360.f * data->back() / (float)iMaximum;
     
    779786    dataPath.arcTo(chartRect, 90.f/*startAngle*/,
    780787                   -1.f * fAngle /*sweepLength*/);
    781     painter.setBrush(pieGradient);
     788    painter.setBrush(conicalGradientForDataSeries(chartRect, iDataIndex));
    782789    painter.drawPath(dataPath);
    783790}
    784791
    785792void UIChart::drawDoughnutChart(QPainter &painter, quint64 iMaximum, int iDataIndex,
    786                                 const QRectF &chartRect, const QRectF &innerRect, int iAlpha)
     793                                const QRectF &chartRect, const QRectF &innerRect)
    787794{
    788795    const QQueue<quint64> *data = m_pMetric->data(iDataIndex);
     
    791798
    792799    /* Draw a whole non-filled circle: */
    793     painter.setPen(QPen(QColor(100, 100, 100, iAlpha), 1));
     800    painter.setPen(QPen(QColor(100, 100, 100, m_iOverlayAlpha), 1));
    794801    painter.drawArc(chartRect, 0, 3600 * 16);
     802    painter.drawArc(innerRect, 0, 3600 * 16);
     803
     804    /* Draw a white filled circle and that the arc for data: */
     805    QPainterPath background = wholeArc(chartRect).subtracted(wholeArc(innerRect));
    795806    painter.setPen(Qt::NoPen);
    796 
    797     /* First draw a white filled circle and that the arc for data: */
    798     QPointF center(chartRect.center());
    799     QPainterPath fillPath;
    800     fillPath.moveTo(center);
    801     fillPath.arcTo(chartRect, 90/*startAngle*/,
    802                    -1 * 360 /*sweepLength*/);
     807    painter.setBrush(QColor(255, 255, 255, m_iOverlayAlpha));
     808    painter.drawPath(background);
     809
     810    /* Draw the doughnut slice for the data: */
     811    float fAngle = 360.f * data->back() / (float)iMaximum;
     812    painter.setBrush(conicalGradientForDataSeries(chartRect, iDataIndex));
     813    painter.drawPath(doughnutSlice(chartRect, innerRect, 90, fAngle));
     814}
     815
     816void UIChart::drawCombinedDoughnutChart(QPainter &painter, quint64  iMaximum,
     817                               const QRectF &chartRect, const QRectF &innerRect)
     818{
     819    int iDataIndex = 0;
     820    const QQueue<quint64> *data = m_pMetric->data(iDataIndex);
     821    if (!data || data->isEmpty())
     822        return;
     823
     824    /* Draw two arcs. one for the inner the other for the outer circle: */
     825    painter.setPen(QPen(QColor(100, 100, 100, m_iOverlayAlpha), 1));
     826    painter.drawArc(chartRect, 0, 3600 * 16);
     827    painter.drawArc(innerRect, 0, 3600 * 16);
     828
     829    /* Draw a translucent white background: */
     830    QPainterPath background = wholeArc(chartRect).subtracted(wholeArc(innerRect));
    803831    painter.setPen(Qt::NoPen);
    804     painter.setBrush(QColor(255, 255, 255, iAlpha));
    805     painter.drawPath(fillPath);
    806 
    807     /* Prepare the gradient for the pie chart: */
    808     QConicalGradient pieGradient;
    809     pieGradient.setCenter(chartRect.center());
    810     pieGradient.setAngle(90);
    811     pieGradient.setColorAt(0, QColor(0, 0, 0, iAlpha));
     832    painter.setBrush(QColor(255, 255, 255, m_iOverlayAlpha));
     833    painter.drawPath(background);
     834
     835    /* Draw a doughnut slice for the first data series: */
     836    float fAngle = 360.f * data->back() / (float)iMaximum;
     837    painter.setBrush(m_dataSeriesColor[iDataIndex]);
     838    painter.drawPath(doughnutSlice(chartRect, innerRect, 90, fAngle));
     839
     840    /* Draw another slice for 2nd data series on top of the first if necessary: */
     841    iDataIndex = 1;
     842    const QQueue<quint64> *data2 = m_pMetric->data(iDataIndex);
     843    if (data2 && !data2->isEmpty())
     844    {
     845        float fAngle2 = 360.f * data2->back() / (float)iMaximum;
     846        painter.setBrush(m_dataSeriesColor[iDataIndex]);
     847        painter.drawPath(doughnutSlice(chartRect, innerRect, 90 - fAngle, fAngle2));
     848    }
     849}
     850
     851QPainterPath UIChart::wholeArc(const QRectF &rectangle)
     852{
     853    QPainterPath arc;
     854    QPointF center(rectangle.center());
     855
     856    // arc.moveTo(center);
     857    // arc.arcTo(rectangle, 90/*startAngle*/,
     858    //                -1 * 360 /*sweepLength*/);
     859
     860    arc.addEllipse(rectangle);
     861    return arc;
     862}
     863
     864QConicalGradient UIChart::conicalGradientForDataSeries(const QRectF &rectangle, int iDataIndex)
     865{
     866    QConicalGradient gradient;
     867    gradient.setCenter(rectangle.center());
     868    gradient.setAngle(90);
     869    gradient.setColorAt(0, QColor(0, 0, 0, m_iOverlayAlpha));
    812870    QColor pieColor(m_dataSeriesColor[iDataIndex]);
    813     pieColor.setAlpha(iAlpha);
    814     pieGradient.setColorAt(1, pieColor);
    815 
    816 
    817     float fAngle = 360.f * data->back() / (float)iMaximum;
    818 
     871    pieColor.setAlpha(m_iOverlayAlpha);
     872    gradient.setColorAt(1, pieColor);
     873    return gradient;
     874}
     875
     876QPainterPath UIChart::doughnutSlice(const QRectF &outerRectangle, const QRectF &innerRectangle, float fStartAngle, float fSweepAngle)
     877{
    819878    QPainterPath subPath1;
    820     subPath1.moveTo(chartRect.center());
    821     subPath1.arcTo(chartRect, 90.f/*startAngle*/,
    822                    -1.f * fAngle /*sweepLength*/);
     879    subPath1.moveTo(outerRectangle.center());
     880    subPath1.arcTo(outerRectangle, fStartAngle,
     881                   -1.f * fSweepAngle);
    823882    subPath1.closeSubpath();
    824883
    825884    QPainterPath subPath2;
    826     subPath2.moveTo(innerRect.center());
    827     subPath2.arcTo(innerRect, 90.f/*startAngle*/,
    828                    -1.f * fAngle /*sweepLength*/);
     885    subPath2.moveTo(innerRectangle.center());
     886    subPath2.arcTo(innerRectangle, fStartAngle,
     887                   -1.f * fSweepAngle);
    829888    subPath2.closeSubpath();
    830889
    831     QPainterPath dataPath = subPath1.subtracted(subPath2);
    832 
    833     painter.setBrush(pieGradient);
    834     painter.drawPath(dataPath);
    835 
     890    return subPath1.subtracted(subPath2);
    836891}
    837892
     
    844899                     QSizeF(m_iPieChartRadius, m_iPieChartRadius));
    845900
    846     int iAlpha = 80;
    847 
    848     /* First draw a doughnut shaped chart for the 1st data series */
    849     // int iDataIndex = 0;
    850     // const QQueue<quint64> *data = m_pMetric->data(iDataIndex);
    851     // if (!data || data->isEmpty())
    852     //     return;
    853901    bool fData0 = m_pMetric->data(0) && !m_pMetric->data(0)->isEmpty();
    854902    bool fData1 = m_pMetric->data(0) && !m_pMetric->data(1)->isEmpty();
     
    858906        QRectF innerRect(QPointF(chartRect.left() + 0.25 * chartRect.width(), chartRect.top() + 0.25 * chartRect.height()),
    859907                         QSizeF(0.5 * chartRect.width(), 0.5 * chartRect.height()));
    860 
     908        /* Draw a doughnut chart where data series are stacked on to of each other: */
     909        drawCombinedDoughnutChart(painter, iMaximum, chartRect, innerRect);
    861910        /* Draw a doughnut shaped chart and then pie chart inside it: */
    862         drawDoughnutChart(painter, iMaximum, 0 /* iDataIndex */, chartRect, innerRect, iAlpha);
    863         drawPieChart(painter, iMaximum, 1 /* iDataIndex */, innerRect, iAlpha);
    864 
     911        // drawDoughnutChart(painter, iMaximum, 0 /* iDataIndex */, chartRect, innerRect);
     912        // drawPieChart(painter, iMaximum, 1 /* iDataIndex */, innerRect, false);
    865913    }
    866914    else if (fData0 && !fData1)
    867         drawPieChart(painter, iMaximum, 0 /* iDataIndex */, chartRect, iAlpha);
     915        drawPieChart(painter, iMaximum, 0 /* iDataIndex */, chartRect);
    868916    else if (!fData0 && fData1)
    869         drawPieChart(painter, iMaximum, 1 /* iDataIndex */, chartRect, iAlpha);
     917        drawPieChart(painter, iMaximum, 1 /* iDataIndex */, chartRect);
    870918}
    871919
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette