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;
}
//========================================================================================
//| 函数名称 | slotPointHoverd
//|--------------------------------------------------------------------------------------
//| 函数功能 | 按钮悬浮时显示当前点的值
//|--------------------------------------------------------------------------------------
//| 输入参数 |
//|--------------------------------------------------------------------------------------
//| 返回参数 | 无
//|--------------------------------------------------------------------------------------
//| 函数设计 | 刘亚鹏 2020-11-05
//========================================================================================
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);
}
}