目录
- 参考
- 角度轴范围是[0,360]时,0度在水平右侧
- .h
- .cpp
参考
Qt数据可视化(QPolarChart雷达图)
默认QPolarChart的范围是[0,360]时,0度在垂直上方
如官方例子QValueAxis角度轴范围是[-100,100]
角度轴范围是[0,360]时,0度在水平右侧
- 原理:
- 角度轴使用范围改为[-90,270],此时0度在水平右侧
- 使用分类轴
QCategoryAxis
代替 数值轴QValueAxis
重新指定 -90 到 0 度之间的标签;
注意:此方法只能实现简单效果;
复杂效果可以使用QGraphicsView
实现顺时针旋转90°(此方法本人在开发遇到缩放比例问题就没有使用)
参考:qt界面旋转
.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QPolarChart>
#include <QChartView>
#include <QScatterSeries>
#include <QList>
#include <QDebug>
#include <QLineSeries>
#include <QTimer>#include <QtCharts/QPolarChart>
#include <QtCharts/QAbstractAxis>
#include <QtCharts/QChart>
#include <QtCharts/QValueAxis>
#include <QtCharts/QCategoryAxis>
#include <QtCharts/QAbstractAxis>
QT_CHARTS_USE_NAMESPACE/*****************************************自定义***********************************************************/
QT_CHARTS_BEGIN_NAMESPACEclass QAbstractSeries;
class QAbstractAxis;class VPolarChart:public QChart
{Q_OBJECTQ_ENUMS(PolarOrientation)Q_FLAGS(PolarOrientations)public:enum PolarOrientation {PolarOrientationRadial = 0x1, // 径向轴,Y:到圆心距离PolarOrientationAngular = 0x2 // 角度轴,X:角度 };Q_DECLARE_FLAGS(PolarOrientations, PolarOrientation)
public:VPolarChart(QGraphicsItem* parent = nullptr, Qt::WindowFlags wFlags = Qt::WindowFlags()) : QChart(QChart::ChartTypePolar, parent, wFlags){};~VPolarChart() {};// 径向轴void addRadialAxis(QValueAxis* radialAxis){if (radialAxis == nullptr || radialAxis->type() == QAbstractAxis::AxisTypeBarCategory) {qWarning("QAbstractAxis::AxisTypeBarCategory is not a supported axis type for polar charts.");return;}QChart::addAxis(radialAxis, Qt::AlignLeft);}// 角度轴void addAngularAxis(QCategoryAxis* angularAxis){if (angularAxis == nullptr || angularAxis->type() == QAbstractAxis::AxisTypeBarCategory) {qWarning("QAbstractAxis::AxisTypeBarCategory is not a supported axis type for polar charts.");return;}angularAxis->setMin(-90);angularAxis->setMax(270);angularAxis->setStartValue(-90);if (angularAxis->categoriesLabels().isEmpty()|| angularAxis->categoriesLabels().size() < 9){angularAxis->append("270", -90); // 添加极坐标的角向标签angularAxis->append("315", -45);angularAxis->append("0", 0);angularAxis->append("45", 45);angularAxis->append("90", 90);angularAxis->append("135", 135);angularAxis->append("180", 180);angularAxis->append("225", 225);angularAxis->append("270", 270);}angularAxis->setLabelsPosition(QCategoryAxis::AxisLabelsPositionOnValue); // 设置标签位置QChart::addAxis(angularAxis, Qt::AlignBottom);}QList<QAbstractAxis*> axes(PolarOrientations polarOrientation = PolarOrientations(PolarOrientationRadial | PolarOrientationAngular), QAbstractSeries* series = nullptr) const {Qt::Orientations orientation(0);if (polarOrientation.testFlag(PolarOrientationAngular)) // 角度轴, X:角度orientation |= Qt::Horizontal; if (polarOrientation.testFlag(PolarOrientationRadial)) // 径向轴,Y:到圆心距离orientation |= Qt::Vertical;return QChart::axes(orientation, series);};static PolarOrientation axisPolarOrientation(QAbstractAxis* axis) {if (axis && axis->orientation() == Qt::Horizontal)return PolarOrientationAngular; // 角度轴elsereturn PolarOrientationRadial; // 径向轴};private:Q_DISABLE_COPY(VPolarChart)
};class VScatterSeries :public QScatterSeries
{
public:VScatterSeries(QObject* parent = nullptr) :QScatterSeries(parent) {};~VScatterSeries() {};void insert(qreal x, qreal y) {x = x > 270 ? x - 360 : x;QXYSeries::append(x,y);}
private:
};QT_CHARTS_END_NAMESPACE/*****************************************自定义***********************************************************/class Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent = 0);~Widget();void initConnect();void timeout();private:VPolarChart*m_ptrChart; // 极坐标图QChartView *m_ptrChartview;QTimer *m_ptrTime;qreal m_rangle; // 角
};#endif // WIDGET_H
.cpp
#include "widget.h"#include <QSplineSeries>Widget::Widget(QWidget* parent): QWidget(parent), m_ptrChart(new VPolarChart), m_ptrChartview(new QChartView(m_ptrChart, this)), m_ptrTime(new QTimer), m_rangle(0)
{// 抗锯齿m_ptrChartview->setRenderHint(QPainter::Antialiasing);// 动画m_ptrChart->setAnimationOptions(QChart::GridAxisAnimations);// 表示曲线QSplineSeries* s = new QSplineSeries();s->append(0, 0);s->append(m_rangle, 270);VScatterSeries* series = new VScatterSeries(); // 创建一个散点绘图数据集对象const qreal angularMax = 270; // 最大角度series->setName("散点");for (int i = 0; i < angularMax; i += 10) {series->insert(i, i); // 向series中添加数据,X:角度 Y:到圆心距离}
// series->setPointLabelsVisible(true);
// series->setPointLabelsFormat("(@xPoint, @yPoint)"); m_ptrChart->legend()->setVisible(true); // 隐藏图例//径向轴Y:到圆心距离QValueAxis* radialAxis = new QValueAxis();radialAxis->setTickCount(3);radialAxis->setLabelFormat("%d");m_ptrChart->addRadialAxis(radialAxis);//角度轴X:角度 QCategoryAxis* angularAxis = new QCategoryAxis();angularAxis->setShadesVisible(true); // 阴影angularAxis->setShadesBrush(QBrush(QColor(249, 249, 255)));m_ptrChart->addAngularAxis(angularAxis);m_ptrChartview->setFixedSize(500, 500); // QChartView 的大小设置为 500x500 像素m_ptrChart->addSeries(series); // 将创建的series添加进图表中m_ptrChart->addSeries(s);series->attachAxis(angularAxis);series->attachAxis(radialAxis);s->attachAxis(angularAxis);s->attachAxis(radialAxis);initConnect();m_ptrTime->start(100);
}
void Widget::initConnect()
{connect(m_ptrTime, &QTimer::timeout, this, &Widget::timeout);
}void Widget::timeout()
{qInfo() << "start timeout";foreach(auto * serie, m_ptrChart->series()) {if (serie == nullptr) continue;//qInfo() << "item->type()" << item->type();if (serie->type() == QSplineSeries::SeriesTypeSpline) {//清空曲线系列的数据点dynamic_cast<QSplineSeries*>(serie)->clear();m_rangle = (m_rangle >= 270)?(-90.): m_rangle+1.5;//向曲线系列中添加数据点dynamic_cast<QSplineSeries*>(serie)->append(0, 0);dynamic_cast<QSplineSeries*>(serie)->append(m_rangle, 270);}}
}
Widget::~Widget() {}