int Nightcharts::GetQuater(double angle)
{
    angle = Angle360(angle);

    if(angle>=0 && angle<90)
        return 1;
    if(angle>=90 && angle<180)
        return 2;
    if(angle>=180 && angle<270)
        return 3;
    if(angle>=270 && angle<360)
        return 4;
}
DiagramWindow::GetQuater(double angle)
{
    angle = Angle360(angle);

    if(angle >= 0 && angle < 90)
    {
        return 1;
    }
    if(angle >= 90 && angle < 180)
    {
        return 2;
    }
    if(angle >= 180 && angle < 270)
    {
        return 3;
    }
    return 4;
}
Example #3
0
int Nightcharts::draw(QPainter *painter)
{
    painter->setRenderHint(QPainter::Antialiasing);
    painter->setPen(Qt::NoPen);

    if (this->ctype == Nightcharts::Pie)
    {
        pW = 0;
        double pdegree = 0;

        //Options
        QLinearGradient gradient(cX+0.5*cW,cY,cX+0.5*cW,cY+cH*2.5);
        gradient.setColorAt(1,Qt::black);

        //Draw
        //pdegree = (360/100)*pieces[i].pPerc;
        if (shadows)
        {
            double sumangle = 0;
            for (int i = 0; i < pieces.size(); i++)
            {
                sumangle += 3.6 * pieces[i].pPerc;
            }
            painter->setBrush(Qt::darkGray);
            painter->drawPie(cX,cY+pW+5,cW,cH,palpha*16,sumangle*16);
        }

        QPen pen;
        pen.setWidth(2);

        for (int i = 0; i < pieces.size(); i++)
        {
            gradient.setColorAt(0, pieces[i].rgbColor);
            painter->setBrush(gradient);
            pen.setColor(pieces[i].rgbColor);
            painter->setPen(pen);
            pdegree = 3.6 * pieces[i].pPerc;
            painter->drawPie(cX, cY, cW, cH, palpha*16, pdegree*16);
            palpha += pdegree;
        }
    }
    else if (this->ctype == Nightcharts::Dpie)
    {
        pW = 50;
        double pdegree = 0;
        QPointF p;

        QLinearGradient gradient(cX - 0.5 * cW, cY + cH/2, cX + 1.5 * cW, cY + cH/2);
        gradient.setColorAt(0,Qt::black);
        gradient.setColorAt(1,Qt::white);
        QLinearGradient gradient_side(cX, cY + cH, cX + cW, cY + cH);
        gradient_side.setColorAt(0,Qt::black);

        double sumangle = 0;

        for (int i = 0; i < pieces.size(); i++)
        {
            sumangle += 3.6 * pieces[i].pPerc;
        }
        if (shadows)
        {
            painter->setBrush(Qt::darkGray);
            painter->drawPie(cX, cY + pW + 5, cW, cH, palpha * 16, sumangle * 16);
        }

        int q = GetQuater(palpha+sumangle);

        if (q ==2 || q==3)
        {
            QPointF p = GetPoint(palpha+sumangle);
            QPointF points[4] =
            {
                QPointF(p.x(), p.y()),
                QPointF(p.x(), p.y() + pW),
                QPointF(cX + cW/2, cY + cH/2 + pW),
                QPointF(cX + cW/2, cY + cH/2)
            };
            gradient_side.setColorAt(1, pieces[pieces.size()-1].rgbColor);
            painter->setBrush(gradient_side);
            painter->drawPolygon(points, 4);
        }
        p = GetPoint(palpha);
        q = GetQuater(palpha);

        if (q ==1 || q==4)
        {
            QPointF points[4] =
            {
                QPointF(p.x(), p.y()),
                QPointF(p.x(), p.y() + pW),
                QPointF(cX + cW/2, cY + cH/2 + pW),
                QPointF(cX + cW/2, cY + cH/2)
            };
            gradient_side.setColorAt(1, pieces[0].rgbColor);
            painter->setBrush(gradient_side);
            painter->drawPolygon(points, 4);
        }

        for (int i = 0;i < pieces.size(); i++)
        {
            gradient.setColorAt(0.5, pieces[i].rgbColor);
            painter->setBrush(gradient);
            pdegree = 3.6 * pieces[i].pPerc;
            painter->drawPie(cX, cY, cW, cH, palpha * 16, pdegree * 16);

            double a_ = Angle360(palpha);
            int q_ = GetQuater(palpha);

            palpha += pdegree;

            double a = Angle360(palpha);
            int q = GetQuater(palpha);

            QPainterPath path;
            p = GetPoint(palpha);

            if((q == 3 || q == 4) && (q_ == 3 || q_ == 4))
            {
                // 1)
                if (a>a_)
                {
                    QPointF p_old = GetPoint(palpha-pdegree);
                    path.moveTo(p_old.x() - 1, p_old.y());
                    path.arcTo(cX, cY, cW, cH, palpha-pdegree, pdegree);
                    path.lineTo(p.x(), p.y() + pW);
                    path.arcTo(cX, cY + pW, cW, cH, palpha, -pdegree);
                }
                // 2)
                else
                {
                    path.moveTo(cX, cY + cH/2);
                    path.arcTo(cX, cY, cW, cH, 180, Angle360(palpha) - 180);
                    path.lineTo(p.x(), p.y() + pW);
                    path.arcTo(cX, cY + pW, cW, cH, Angle360(palpha), -Angle360(palpha) + 180);
                    path.lineTo(cX, cY + cH/2);

                    path.moveTo(p.x(), p.y());
                    path.arcTo(cX, cY, cW, cH, palpha-pdegree, 360 - Angle360(palpha - pdegree));
                    path.lineTo(cX + cW, cY + cH/2 + pW);
                    path.arcTo(cX, cY + pW, cW, cH, 0, -360 + Angle360(palpha - pdegree));
                }

            }
            // 3)
            else if((q == 3 || q == 4) && (q_ == 1 || q_ == 2) && a>a_ )
            {
                path.moveTo(cX,cY+cH/2);
                path.arcTo(cX,cY,cW,cH,180,Angle360(palpha)-180);
                path.lineTo(p.x(),p.y()+pW);
                path.arcTo(cX,cY+pW,cW,cH,Angle360(palpha),-Angle360(palpha)+180);
                path.lineTo(cX,cY+cH/2);
            }
            // 4)
            else if((q == 1 || q == 2) && (q_ == 3 || q_ == 4) && a<a_)
            {
                p = GetPoint(palpha-pdegree);
                path.moveTo(p.x(),p.y());
                path.arcTo(cX,cY,cW,cH,palpha-pdegree,360-Angle360(palpha-pdegree));
                path.lineTo(cX+cW,cY+cH/2+pW);
                path.arcTo(cX,cY+pW,cW,cH,0,-360+Angle360(palpha-pdegree));
            }
            // 5)
            else if((q ==1 || q==2) && (q_==1 || q_==2) && a<a_)
            {
                path.moveTo(cX,cY+cH/2);
                path.arcTo(cX,cY,cW,cH,180,180);
                path.lineTo(cX+cW,cY+cH/2+pW);
                path.arcTo(cX,cY+pW,cW,cH,0,-180);
                path.lineTo(cX,cY+cH/2);
            }
            if (!path.isEmpty())
            {
                gradient_side.setColorAt(1,pieces[i].rgbColor);
                painter->setBrush(gradient_side);
                painter->drawPath(path);
            }
        }
    }
    else if (this->ctype==Nightcharts::Histogramm)
    {
        double pDist = 15;
        double pW = (cW-(pieces.size())*pDist)/pieces.size();

        QLinearGradient gradient(cX + cW/2, cY, cX + cW/2, cY + cH);
        gradient.setColorAt(0,Qt::black);
        QPen pen;
        pen.setWidth(3);

        for (int i = 0;i < pieces.size(); i++)
        {
            if (shadows)
            {
                painter->setPen(Qt::NoPen);
                painter->setBrush(Qt::darkGray);
                painter->drawRect(cX+pDist+i*(pW + pDist)-pDist/2,cY+cH-1,pW,-cH/100*pieces[i].pPerc+pDist/2-5);
            }
            gradient.setColorAt(1,pieces[i].rgbColor);
            painter->setBrush(gradient);
            pen.setColor(pieces[i].rgbColor);
            painter->setPen(pen);
            painter->drawRect(cX+pDist+i*(pW + pDist),cY+cH,pW,-cH/100*pieces[i].pPerc-5);
            QString label = QString::number(pieces[i].pPerc)+"%";
            painter->setPen(Qt::SolidLine);
            painter->drawText(cX+pDist+i*(pW + pDist)+pW/2-painter->fontMetrics().width(label)/2,cY+cH-cH/100*pieces[i].pPerc-painter->fontMetrics().height()/2,label);
        }
        painter->setPen(Qt::SolidLine);
        for (int i = 1; i < 10; i++)
        {
            painter->drawLine(cX - 3, cY + cH/10 * i, cX + 3, cY + cH/10 * i);    //§Õ§Ö§Ý§Ö§ß§Ú§ñ §á§à §à§ã§Ú Y
            //painter->drawText(cX-20,cY+cH/10*i,QString::number((10-i)*10)+"%");
        }
        painter->drawLine(cX,cY+cH,cX,cY);         //§à§ã§î Y
        painter->drawLine(cX,cY,cX+4,cY+10);       //§ã§ä§â§Ö§Ý§Ü§Ú
        painter->drawLine(cX,cY,cX-4,cY+10);
        painter->drawLine(cX,cY+cH,cX+cW,cY+cH);   //§à§ã§î §·

    }
    return 0;
}
void DiagramWindow::paintEvent(QPaintEvent *event)
{
    (void)event;
    QPainter painter(this);  
    painter.setRenderHints(QPainter::Antialiasing, true);

    pW = 50 - float(coords.y()) / this->height() * 50;
    cH = float(coords.y()) / this->height() * 150;

    if (cH > 150 / 3 + 30)   //  /3 == *60/180
    {
        cH = 150 / 3 + 30;
        pW = 50 - cH / 150 * 50;
    }
    else if (cH < 150 / 6 + 30)    //  /6 == *30/180
    {
        cH = 150 / 6 + 30;
        pW = 50 - cH / 150 * 50;
    }

    QLinearGradient gradient(cX - 0.5 * cW, cY + cH / 2, cX + 1.5 * cW, cY + cH / 2);
    gradient.setColorAt(0, Qt::black);
    gradient.setColorAt(1, Qt::white);
    QLinearGradient gradientSide(cX, cY + cH, cX + cW ,cY + cH);
    gradientSide.setColorAt(0, Qt::black);

    double pAlpha = float(coords.x()) / this->width() * 360;
    if (pAlpha > 360)
    {
        pAlpha = 360;
    }
    else if (pAlpha < 0)
    {
        pAlpha = 0;
    }

    auto data = m_model->getData();
    float allPopulation = 0;
    for (int i = 0; i < data.size(); i++)
    {
        allPopulation += data[i].population;
    }

    double pDegree = 0;
    QPointF p;
    QVector<QColor> colors = {Qt::red, Qt::green, Qt::blue, Qt::cyan, Qt::magenta, Qt::yellow, Qt::gray};

    for (int i = 0; i <  data.size(); i++)
    {
        gradient.setColorAt(0.5, colors[i % 7]);
        painter.setBrush(gradient);
        pDegree = (data[i].population / allPopulation) * 360;
        painter.drawPie(cX, cY, cW, cH, pAlpha * 16, pDegree * 16);

        double alphaPrev = Angle360(pAlpha);
        int quatPrev = GetQuater(pAlpha);

        pAlpha += pDegree;

        double alphaNext = Angle360(pAlpha);
        int quatNext = GetQuater(pAlpha);

        QPainterPath path;
        p = GetPoint(pAlpha);

        if((quatNext == 3 || quatNext == 4) && (quatPrev == 3 || quatPrev == 4))
        {
            if (alphaNext > alphaPrev)
            {
                QPointF pOld = GetPoint(pAlpha - pDegree);
                path.moveTo(pOld.x() - 1, pOld.y());
                path.arcTo(cX, cY, cW, cH, pAlpha - pDegree, pDegree);
                path.lineTo(p.x(), p.y() + pW);
                path.arcTo(cX, cY + pW, cW, cH, pAlpha, -pDegree);
            }
            else
            {
                path.moveTo(cX,cY + cH / 2);
                path.arcTo(cX, cY, cW, cH, 180, Angle360(pAlpha) - 180);
                path.lineTo(p.x(), p.y() + pW);
                path.arcTo(cX, cY + pW,cW,cH, Angle360(pAlpha), -Angle360(pAlpha) + 180);
                path.lineTo(cX, cY + cH / 2);

                path.moveTo(p.x(), p.y());
                path.arcTo(cX, cY, cW, cH, pAlpha - pDegree, 360 - Angle360(pAlpha - pDegree));
                path.lineTo(cX + cW, cY + cH/2 + pW);
                path.arcTo(cX, cY + pW, cW, cH, 0, -360 + Angle360(pAlpha - pDegree));
             }
        }
        else if((quatNext == 3 || quatNext == 4) && (quatPrev == 1 || quatPrev == 2) && alphaNext > alphaPrev )
        {
            path.moveTo(cX, cY + cH / 2);
            path.arcTo(cX, cY, cW, cH, 180, Angle360(pAlpha) - 180);
            path.lineTo(p.x(), p.y() + pW);
            path.arcTo(cX, cY + pW, cW, cH, Angle360(pAlpha), -Angle360(pAlpha) + 180);
            path.lineTo(cX, cY + cH / 2);
        }
        else if((quatNext == 1 || quatNext == 2) && (quatPrev == 3 || quatPrev == 4) && alphaNext < alphaPrev)
        {
            p = GetPoint(pAlpha - pDegree);
            path.moveTo(p.x(), p.y());
            path.arcTo(cX, cY, cW, cH, pAlpha - pDegree, 360 - Angle360(pAlpha - pDegree));
            path.lineTo(cX + cW, cY + cH / 2 + pW);
            path.arcTo(cX, cY + pW, cW, cH, 0, -360 + Angle360(pAlpha - pDegree));
        }
        if (!path.isEmpty())
        {
            gradientSide.setColorAt(1, colors[i]);
            painter.setBrush(gradientSide);
            painter.drawPath(path);
        }
    }
}