QChart空心折线图,双坐标轴显示不同参数

4 篇文章 1 订阅

QChart空心折线图,双坐标轴显示不同参数

界面显示

在这里插入图片描述

说明

过几天再详细讲解,这段时间有些忙hhh

附带代码

#ifndef FORM_SCATTER_H
#define FORM_SCATTER_H

#include <QWidget>
#include <QLabel>
#include <QCategoryAxis>
#include <qchartview.h>
#include <QLineSeries>
#include <QScatterSeries>
QT_CHARTS_USE_NAMESPACE


namespace Ui {
class Form_Scatter;
}

class Form_Scatter : public QWidget
{
    Q_OBJECT

public:
    explicit Form_Scatter(QWidget *parent = nullptr);
    ~Form_Scatter();
public:
    /**
     * @brief initChart             初始化图表
     */
    void initChart();

    void SetXYAxis(std::vector<QString> TimeX);
    /**
     * @brief bulidChart
     */
    void bulidChart(std::map<QString, std::vector<QString> > mapData);

    /**
     * @brief prepareData
     */
    void Clear();
private slots:
    void slotPointHoverd(const QPointF &point, bool state);  //按钮悬浮
protected:
    void mousePressEvent(QMouseEvent *event);
    void wheelEvent(QWheelEvent *event);

private:
    bool m_PMshow;      //PM轴是否显示
    float m_Ymax,m_YPMmax;  //Y轴最大值   PM 的Y轴最大值
    QCategoryAxis *m_axisX; //X轴
    QValueAxis *m_axisY,*m_axisYPM; //Y轴 PM的Y轴
    QLabel *m_valueLabel;   //节点值的标签显示
    QList<QColor> m_colorList;  //颜色链表
private:
    Ui::Form_Scatter *ui;
};

#endif // FORM_SCATTER_H

#include "form_scatter.h"
#include "form_scatter.h"
#include "ui_form_scatter.h"
#include <QLegendMarker>
#include <QLegend>
Form_Scatter::Form_Scatter(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form_Scatter)
{
    ui->setupUi(this);
    m_colorList.push_back(qRgb(255,0,0));
    m_colorList.push_back(qRgb(0,255,0));
    m_colorList.push_back(qRgb(0,0,255));
    m_colorList.push_back(qRgb(255,0,255));
    m_colorList.push_back(qRgb(255,144,0));
    m_Ymax = 10;
    m_YPMmax = 10;

    m_PMshow= false;
    initChart();

}

Form_Scatter::~Form_Scatter()
{

    Clear();
    delete  m_axisX;
    delete m_axisY;
    delete m_axisYPM;
    delete ui;
}
void Form_Scatter::initChart()
{
    m_valueLabel = new QLabel(this);
    m_valueLabel->setStyleSheet(QString("QLabel{color:#1564FF; font-family:\"Microsoft Yahei\"; font-size:12px; font-weight:bold;"
                                        " background-color:rgba(21, 100, 255, 51); border-radius:4px; text-align:center;}"));
    m_valueLabel->setFixedSize(64, 24);
    m_valueLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    m_valueLabel->hide();

    QChart *chart = new QChart();
    chart->legend()->setVisible(true);
    ui->chartView->setChart(chart);
    ui->chartView->setRenderHint(QPainter::Antialiasing);

    chart->setBackgroundBrush(QBrush(QColor(248, 251, 255)));
    chart->legend()->setMarkerShape(QLegend::MarkerShapeFromSeries);

}

void Form_Scatter::SetXYAxis(std::vector<QString> TimeX)
{
    //坐标轴X
    m_axisX = new QCategoryAxis();
    m_axisX->setMin(0);
    m_axisX->setMax(20);

    m_axisX->setStartValue(5);
    m_axisX->append("", 0); //第一个点空住为了清晰
    m_axisX->setLabelsAngle(80);

    m_axisX->setLabelsFont(QFont("黑体",6,QFont::Black));
    m_axisX->setLabelsPosition(QCategoryAxis::AxisLabelsPositionOnValue);
    int LoopSize = 1;
    if(TimeX.size()>=10)
        LoopSize  =TimeX.size()/10;
    if(TimeX.size()>=10&&TimeX.size()<20)
        LoopSize = 2;
    int count = 1;
    for (auto it = TimeX.begin();it!=TimeX.end();it++)
    {
        if(((count-1) % LoopSize ==0)||count == 1)
        m_axisX->append(*it,count);
        count++;
    }
    m_axisX->setTickCount(32);//主分隔个数
    m_axisX->setGridLineVisible(false);
    m_axisX->setMinorGridLineVisible(false);
    m_axisX->setLabelFormat("yyyy.MM.dd");
    //坐标轴Y
    m_axisY = new QValueAxis();
    m_axisY->setRange(0, 10);
    m_axisY->setTickCount(6);
    m_axisY->setLabelFormat("%.4f");
    m_axisY->setMinorTickCount(0);
    m_axisY->setTitleText("元素浓度 ng/m3");
    m_axisYPM = new QValueAxis();
    m_axisYPM->setRange(0, 10);
    m_axisYPM->setTickCount(6);
    m_axisYPM->setLabelFormat("%.4f");
    m_axisYPM->setTitleText("PM浓度 μg/m3");
    m_axisYPM->setMinorTickCount(0);
    ui->chartView->chart()->addAxis(m_axisX,Qt::AlignBottom);
    ui->chartView->chart()->addAxis(m_axisY,Qt::AlignLeft);
    ui->chartView->chart()->addAxis(m_axisYPM,Qt::AlignRight);

}

void Form_Scatter::bulidChart(std::map<QString,std::vector<QString>> mapData)
{
    Clear();

    int i = 0;
    for (auto it = mapData.begin();it!=mapData.end();it++)
    {
        QChart *chart = ui->chartView->chart();
        // chart->removeAllSeries();

        m_colorList.push_back(qRgb(255,144,0));
        //折线图
        QLineSeries *series0 = new QLineSeries();
        series0->setName(it->first);
        QPen pen;
        pen.setStyle(Qt::SolidLine);
        pen.setWidth(4);
        pen.setColor(m_colorList.at(i));
        series0->setPen(pen);//折现序列的线条设置

        //散点图(用于鼠标悬浮上显示的边框)
        QScatterSeries *series1 = new QScatterSeries();
        series1->setMarkerShape(QScatterSeries::MarkerShapeCircle);//圆形的点
        QRadialGradient radialGrad(QPointF(100, 100), 100);
        //         radialGrad.setColorAt(0, QColor(255, 255, 255));
        //         radialGrad.setColorAt(0.9, QColor(255, 255, 255));
        //         radialGrad.setColorAt(0.91, QColor(255, 0, 0));
        //         radialGrad.setColorAt(1, QColor(212, 227, 255));
        series1->setName(it->first);
        series1->setBrush(QBrush(radialGrad));//背景颜色
        series1->setMarkerSize(18);                     //点大小


        //散点图(用于正常的边框)
        QScatterSeries *series2 = new QScatterSeries();
        series2->setMarkerShape(QScatterSeries::MarkerShapeCircle);//圆形的点
        series2->setBorderColor(m_colorList.at(i));  //边框颜色
        series2->setBrush(QBrush(m_colorList.at(i)));//背景颜色
        series2->setMarkerSize(12);                     //点大小
        series2->setName(it->first);
        connect(series2, &QScatterSeries::hovered, this, &Form_Scatter::slotPointHoverd);//用于鼠标移动到点上显示数值


        //散点图(用于中心)
        QScatterSeries *series3 = new QScatterSeries();
        series3->setMarkerShape(QScatterSeries::MarkerShapeCircle);//圆形的点
        series3->setBorderColor(Qt::white);//边框颜色
        series3->setBrush(QBrush(Qt::white));//背景颜色
        series3->setMarkerSize(6);//点大小
        series3->setName(it->first);
        connect(series3, &QScatterSeries::hovered, this, &Form_Scatter::slotPointHoverd);//用于鼠标移动到点上显示数值

        chart->addSeries(series0);
        chart->addSeries(series1);
        chart->addSeries(series2);
        chart->addSeries(series3);


        QPen axisPen;
        axisPen.setColor(QColor(231,238,251));
        axisPen.setStyle(Qt::DotLine);
        axisPen.setWidth(2);
        m_axisY->setGridLinePen(axisPen);

        if(it->first == "PM")
        {
            series0->attachAxis(m_axisX);
            series0->attachAxis(m_axisYPM);
            series1->attachAxis(m_axisX);
            series1->attachAxis(m_axisYPM);
            series2->attachAxis(m_axisX);
            series2->attachAxis(m_axisYPM);
            series3->attachAxis(m_axisX);
            series3->attachAxis(m_axisYPM);
        }
        else
        {
            series0->attachAxis(m_axisX);
            series0->attachAxis(m_axisY);
            series1->attachAxis(m_axisX);
            series1->attachAxis(m_axisY);
            series2->attachAxis(m_axisX);
            series2->attachAxis(m_axisY);
            series3->attachAxis(m_axisX);
            series3->attachAxis(m_axisY);
        }



        int countVal = 0;
        for (auto itsec = it->second.begin();itsec!=it->second.end();itsec++)
        {
            //取Y轴最大值,动态设置Y轴值


            if(it->first == "PM")
            {
                if(itsec->toFloat()>m_YPMmax)
                {
                    m_YPMmax = itsec->toFloat();
                }
            }
            else if(itsec->toFloat()>m_Ymax)
            {
                m_Ymax = itsec->toFloat();
            }

            countVal++;
            series0->append(countVal, itsec->toFloat());
            series2->append(countVal, itsec->toFloat());
            series3->append(countVal, itsec->toFloat());
        }
        m_axisX->setRange(0,it->second.size()+1);

        i++;
    }
    m_axisY->setRange(0,m_Ymax*1.1);
    m_axisYPM->setRange(0,m_YPMmax*1.1);
    int count = 0;
    foreach (QLegendMarker* marker, ui->chartView->chart()->legend()->markers())
    {
        count ++;
        if((count%3 == 0)||(count%2 == 0))
        {
            if(marker->type() == QLegendMarker::LegendMarkerTypeXY)
            {
                marker->setVisible(false);
            }
        }
        if(count == 4)
            count = 0;
    }
}



void Form_Scatter::Clear()
{

    ui->chartView->chart()->removeAllSeries();
    //    foreach (QXYSeries * pscatter, m_XYSerieslist)
    //        delete pscatter;
}

void Form_Scatter::slotPointHoverd(const QPointF &point, bool state)
{
    if (state) {
        m_valueLabel->setText(QString::asprintf("%1.4f", point.y()));

        QPoint curPos = mapFromGlobal(QCursor::pos());
        m_valueLabel->move(curPos.x() - m_valueLabel->width() / 2, curPos.y() - m_valueLabel->height() * 1.5);//移动数值

        m_valueLabel->show();//显示出来

        //显示被选中点的边框
        QScatterSeries *series1 = (QScatterSeries *)ui->chartView->chart()->series().at(1);
        series1->clear();
        series1->append(point);
        series1->setVisible(true);
    }
    else {
        m_valueLabel->hide();//进行
    }


}

void Form_Scatter::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::RightButton)
    {
        ui->chartView->chart()->zoomReset();
    }
}


void Form_Scatter::wheelEvent(QWheelEvent *event)
{
    float a = ui->chartView->chart()->scale();
    if (event->delta() > 0 && ui->chartView->chart()->scale()<2)
    {//放大
        ui->chartView->chart()->zoom(1.05);
    }
    if (event->delta() < 0 && ui->chartView->chart()->scale()>0.5)
    {//缩小
        ui->chartView->chart()->zoom(0.95);
    }
}


  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值