实现极坐标图表QPolarChart的角度轴范围是[0,360]时,0度在水平右侧

目录

  • 参考
  • 角度轴范围是[0,360]时,0度在水平右侧
  • .h
  • .cpp

参考

Qt数据可视化(QPolarChart雷达图)

默认QPolarChart的范围是[0,360]时,0度在垂直上方
如官方例子QValueAxis角度轴范围是[-100,100]
实现极坐标图表QPolarChart的角度轴范围是[0,360]时,0度在水平右侧_第1张图片

角度轴范围是[0,360]时,0度在水平右侧

实现极坐标图表QPolarChart的角度轴范围是[0,360]时,0度在水平右侧_第2张图片



  • 原理:
  • 角度轴使用范围改为[-90,270],此时0度在水平右侧
  • 使用分类轴QCategoryAxis 代替 数值轴QValueAxis 重新指定 -90 到 0 度之间的标签;

注意:此方法只能实现简单效果;
复杂效果可以使用QGraphicsView实现顺时针旋转90°(此方法本人在开发遇到缩放比例问题就没有使用)
参考:qt界面旋转

.h

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
QT_CHARTS_USE_NAMESPACE

/*****************************************自定义***********************************************************/
QT_CHARTS_BEGIN_NAMESPACE

class QAbstractSeries;
class QAbstractAxis;

class VPolarChart:public QChart
{
    Q_OBJECT
	Q_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;		// 角度轴
		else
			return 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_OBJECT

   public:
    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 

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() {}

你可能感兴趣的:(QT_C++,qt)