void toBarChart::paintChart(QPainter *p, QRect &rect)
{
    QFontMetrics fm = p->fontMetrics();

    if (!Zooming)
    {
        if (MinAuto)
        {
            bool first = true;
            std::list<std::list<double> >::reverse_iterator i = Values.rbegin();
            if (i != Values.rend())
            {
                for (std::list<double>::iterator j = (*i).begin();j != (*i).end();j++)
                {
                    if (first)
                    {
                        first = false;
                        zMinValue = *j;
                    }
                    else if (zMinValue > *j)
                        zMinValue = *j;
                }
            }
        }
        if (MaxAuto)
        {
            bool first = true;
            std::list<double> total;
            std::list<bool>::iterator e = Enabled.begin();
            {
                for (std::list<std::list<double> >::iterator i = Values.begin();i != Values.end();i++)
                {
                    std::list<double>::iterator k = total.begin();
                    if (e == Enabled.end() || *e)
                    {
                        for (std::list<double>::iterator j = (*i).begin();j != (*i).end();j++)
                        {
                            if (k == total.end())
                            {
                                total.insert(total.end(), *j);
                                k = total.end();
                            }
                            else
                            {
                                *k += *j;
                                k++;
                            }
                        }
                    }
                    if (e != Enabled.end())
                        e++;
                }
            }
            for (std::list<double>::iterator i = total.begin();i != total.end();i++)
            {
                if (first)
                {
                    first = false;
                    zMaxValue = *i;
                }
                else if (zMaxValue < *i)
                    zMaxValue = *i;
            }
        }
        if (!MinAuto)
            zMinValue = MinValue;
        else
        {
            zMinValue = round(zMinValue, false);
            MinValue = zMinValue;
        }
        if (!MaxAuto)
            zMaxValue = MaxValue;
        else
        {
            zMaxValue = round(zMaxValue, true);
            MaxValue = zMaxValue;
        }
    }

    paintTitle(p, rect);
    paintLegend(p, rect);
    paintAxis(p, rect);

    std::list<QPolygon> Points;
    int cp = 0;
    int samples = countSamples();
    int zeroy = int(rect.height() - 2 - ( -zMinValue / (zMaxValue - zMinValue) * (rect.height() - 4)));
    if (samples > 1)
    {
        const QMatrix &mtx = p->worldMatrix();
        p->setClipRect(int(mtx.dx() + 2), int(mtx.dy() + 2), rect.width() - 3, rect.height() - 3);
        if (Zooming)
            p->drawText(2, 2, rect.width() - 4, rect.height() - 4,
                        Qt::AlignLeft | Qt::AlignTop, tr("Zoom"));
        std::list<bool>::reverse_iterator e = Enabled.rbegin();
        for (std::list<std::list<double> >::reverse_iterator i = Values.rbegin();i != Values.rend();i++)
        {
            if (e == Enabled.rend() || *e)
            {
                std::list<double> &val = *i;
                int count = 0;
                int skip = SkipSamples;
                QPolygon a(samples + 10);
                int x = rect.width() - 2;
                for (std::list<double>::reverse_iterator j = val.rbegin();j != val.rend() && x >=
                        2;
                        j++)
                {
                    if (skip > 0)
                        skip--;
                    else
                    {
                        int val = int(rect.height() - 2 - ((*j - zMinValue) / (zMaxValue - zMinValue) * (rect.height() - 4)));
                        x = rect.width() - 2 - count * (rect.width() - 4) / (samples - 1);
                        a.setPoint(count, x, val);
                        count++;
                        if (count >= samples)
                            break;
                    }
                }
                a.resize(count*2);
                Points.insert(Points.end(), a);
            }
            cp++;
            if (e != Enabled.rend())
                e++;
        }
    }

    std::map<int, int> Bottom;
    std::list<bool>::reverse_iterator e = Enabled.rbegin();
    for (std::list<QPolygon>::iterator i = Points.begin();i != Points.end();)
    {
        while (e != Enabled.rend() && !*e)
        {
            cp--;
            e++;
        }
        if (e != Enabled.rend())
            e++;
        cp--;

        QPolygon a = *i;
        int lx = 0;
        int lb = 0;
        for (int j = 0;j < a.size() / 2;j++)
        {
            int x, y;
            a.point(j, &x, &y);
            if (Bottom.find(x) == Bottom.end())
                Bottom[x] = 0;
            if (lx != x)
                lb = Bottom[x];
            a.setPoint(a.size() - 1 - j, x, zeroy - lb);
            y -= lb;
            a.setPoint(j, x, y);
            Bottom[x] = zeroy - y;
            lx = x;
        }

        p->save();
        QBrush brush(toChartBrush(cp));
        p->setBrush(brush.color());
        p->drawPolygon(a);
        if (brush.style() != Qt::SolidPattern)
        {
            p->setBrush(QBrush(Qt::white, brush.style()));
            p->drawPolygon(a);
        }
        p->restore();
        i++;
    }
}
Exemplo n.º 2
0
void toLegendChart::paintEvent(QPaintEvent *)
{
    int height, items;
    std::list<int> widths = sizeHint(height, items);

    int width = 4;
    {
        for (std::list<int>::iterator i = widths.begin(); i != widths.end(); i++)
            width += (*i) + 12;
    }

    QPainter p(this);
    QFontMetrics fm = fontMetrics();

    if (!Title.isEmpty())
    {
        p.save();
        QFont f = p.font();
        f.setBold(true);
        p.setFont(f);
        QRect bounds = fm.boundingRect(0, 0,
                                       toLegendChart::width(),
                                       toLegendChart::height(), FONT_ALIGN, Title);
        p.drawText(0, 2,
                   toLegendChart::width() - 4,
                   toLegendChart::height(), Qt::AlignHCenter | Qt::AlignTop, Title);
        p.restore();
        p.translate(0, bounds.height() + 2);
    }

    int cx = 2;
    int cy = 4;
    p.save();
    p.setBrush(Qt::white);
    p.drawRect(2, 2, width, height + 4);
    p.restore();
    int cur = 0;
    std::list<int>::iterator j = widths.begin();
    int cp = 0;
    for (std::list<QString>::iterator i = Labels.begin(); i != Labels.end(); i++)
    {
        if (!(*i).isEmpty() && *i != " ")
        {
            if (cur == items)
            {
                cx += *j + 12;
                cy = 4;
                cur = 0;
                j++;
            }
            QRect bounds = fm.boundingRect(cx + 12, cy, 100000, 100000, FONT_ALIGN, *i);
            p.drawText(bounds, FONT_ALIGN, *i);
            p.save();
            QBrush brush(toChartBrush(cp));
            p.setBrush(brush.color());
            p.drawRect(cx + 2, cy + bounds.height() / 2 - fm.ascent() / 2, 8, fm.ascent());
            if (brush.style() != Qt::SolidPattern)
            {
                p.setBrush(QBrush(Qt::white, brush.style()));
                p.drawRect(cx + 2, cy + bounds.height() / 2 - fm.ascent() / 2, 8, fm.ascent());
            }
            p.restore();
            cy += bounds.height();
            cur++;
        }
        cp++;
    }
}