目錄
- 參考
- 角度軸范圍是[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() {}