Qt使用QCustomplot绘制雷达图(附源代码)

QCustomplot是一个强大开源的绘图工具,下面简单介绍使用QCustomplot绘制雷达图。

1、首先需要新建一个QWidget,并将widget提升位QCustomplot;

2、初始化雷达图

/*QCustomplot初始化*/
void widgetQCustomplotInit(QCustomPlot *widget, int graphCount, QStringList nameList)
{
	/*雷达图初始化*/
		//设置默认追踪鼠标,否则在触发鼠标移动时,必须先点一下才有效
		widget->setMouseTracking(true);
		QLinearGradient plotGradient;
		plotGradient.setColorAt(0, QColor(23, 40, 68));
		widget->setBackground(plotGradient);      // 设置背景颜色

		widget->legend->setVisible(false);//显示图标
		widget->xAxis->setVisible(false); // 不显示 x 轴
		widget->yAxis->setVisible(false); // 不显示 y 轴
		widget->yAxis->rescale(); // 不设置 y 轴范围,让其自适应

		/*设置x/y轴范围-15,15*/
		int radar_R = 10;
		widget->xAxis->setRange(-radar_R - 3, radar_R + 3);
		widget->yAxis->setRange(-radar_R - 3, radar_R + 3);
		/*绘制雷达个数*/
		QVector<QPair<double, double>>	vec_xy = calculatePolygonVertices(graphCount, radar_R);/*graphCount顶点个数, radar_R为半径*/
		for (int i = 0; i < graphCount; i++)
		{
			widget->addGraph();
			int af = widget->graphCount();
			widget->graph(widget->graphCount() - 1)->setPen(QPen(QColor(40, 80, 150))); // 第一个图的线条颜色rgba(40, 80, 150)
			widget->graph(widget->graphCount() - 1)->setSmooth(true);//添加平滑曲线
			widget->graph(widget->graphCount() - 1)->setData(QVector<double>() << 0 << 0 + vec_xy[i].first, QVector<double>() << 0 << vec_xy[i].second);

			// 创建一个文本项,显示标签
			QCPItemText *textLabel = new QCPItemText(widget);
			if (vec_xy[i].first > 0)
				textLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignBottom);
			else
				textLabel->setPositionAlignment(Qt::AlignRight | Qt::AlignBottom);
			textLabel->position->setCoords(vec_xy[i].first, vec_xy[i].second); // 设置文本位置为线段的终点
			textLabel->setText(nameList[i]); // 设置文本内容
			textLabel->setFont(QFont("Aqency FB", 8)); // 设置文本字体
			textLabel->setColor(Qt::white);        //设置字体颜色
			 // 设置背景透明
			textLabel->setBrush(Qt::transparent); // 设置背景为透明
		}
		/*绘制雷达网格*/
		for (int i = 1; i < radar_R - 1; i++)
		{
			QVector<QPair<double, double>>	vec_xy = calculatePolygonVertices(graphCount, i);/*graphCount顶点个数, radar_R为半径*/
			QVector<double> vec_x(graphCount+2), vec_y(graphCount + 2);
			for (int j = 0; j < vec_xy.size(); j++)
			{
				vec_x[j] = vec_xy[j].first;
				vec_y[j] = vec_xy[j].second;
			}
			// 将第一个顶点添加到最后,以便形成闭合图形
			vec_x[graphCount] = vec_x[0];
			vec_y[graphCount] = vec_y[0];
			vec_x[graphCount + 1] = vec_x[1];
			vec_y[graphCount + 1] = vec_y[1];

			widget->addGraph();
			widget->graph(widget->graphCount() - 1)->setPen(QPen(QColor(40, 80, 150))); // 第一个图的线条颜色rgba(40, 80, 150)
			widget->graph(widget->graphCount() - 1)->setData(vec_x, vec_y, true);
		}
		// 最后,重绘图表
		widget->replot();
}

2、计算雷达图雷达顶点

/*计算雷达图每个顶点坐标*/
QVector<QPair<double, double>> calculatePolygonVertices(int n, double R)
{
	QVector<QPair<double, double>>	vec_xy;
	QPair<double, double> temp_pir;
	for (int k = 0; k < n; ++k) {
		// 计算每个顶点的角度
		double theta_k = (2 * M_PI * k / n) + (M_PI / 2); // 90度偏移
		double x_k = R * cos(theta_k);
		double y_k = R * sin(theta_k);
		temp_pir.first = x_k; temp_pir.second = y_k;
		vec_xy.push_back(temp_pir); 
	}
	return vec_xy;
}

/*计算雷达图每个顶点坐标*/
QVector<QPair<double, double>> calculatePolygonVertices(int n, QVector<double> vec_R)
{
	QVector<QPair<double, double>>	vec_xy;
	QPair<double, double> temp_pir;

	for (int k = 0; k < vec_R.size(); ++k) {
		// 计算每个顶点的角度
		double theta_k = (2 * M_PI * k / n) + (M_PI / 2); // 90度偏移
		double x_k = vec_R[k] * cos(theta_k);
		double y_k = vec_R[k] * sin(theta_k);
		temp_pir.first = x_k; temp_pir.second = y_k;
		vec_xy.push_back(temp_pir);
	}
	return vec_xy;
}

3、雷达图赋值

/*QCustomplot赋值*/
void widgetQCustomplotSetData(QCustomPlot *widget, QStringList nameList, QVector<double> vec_value, QMap<QString, QVector<double>> dataX, QMap<QString, QVector<double>> dataY)
{
	/*绘制雷达图*/
		QVector<double> vec_x(nameList.size() + 1), vec_y(nameList.size() + 1);
		for (int j = 0; j < nameList.size(); j++)
		{
			if (dataX.contains(nameList[j]) && dataY.contains(nameList[j]))
			{
				vec_x[j] = dataX[nameList[j]][0];
				vec_y[j] = dataY[nameList[j]][0];
			}
		}
		// 将第一个顶点添加到最后,以便形成闭合图形
		vec_x[nameList.size()] = vec_x[0];
		vec_y[nameList.size()] = vec_y[0];
		
        QVector<double> vec_x1, vec_y1, vec_x2, vec_y2;
		if (vec_x.size() % 2 == 0)
		{
			vec_x1 = vec_x.mid(0, vec_x.size() / 2);
			vec_y1 = vec_y.mid(0, vec_y.size() / 2);
			vec_x2 = vec_x.mid(vec_x.size() / 2 - 1, vec_x.size() / 2 + 1);
			vec_y2 = vec_y.mid(vec_y.size() / 2 - 1, vec_y.size() / 2 + 1);
		}
		else
		{
			vec_x1 = vec_x.mid(0, vec_x.size() / 2);
			vec_y1 = vec_y.mid(0, vec_y.size() / 2);
			vec_x2 = vec_x.mid(vec_x.size() / 2 - 1, vec_x.size() / 2 + 2);
			vec_y2 = vec_y.mid(vec_y.size() / 2 - 1, vec_y.size() / 2 + 2);
		}

		widget->addGraph();
		// 设置多边形的填充颜色
		widget->graph(widget->graphCount() - 1)->setBrush(QBrush(QColor(40, 80, 150)));  // Set the brush  if needed
		widget->graph(widget->graphCount() - 1)->setPen(QPen(Qt::green)); // 第一个图的线条颜色rgba(40, 80, 150)
		widget->graph(widget->graphCount() - 1)->setData(vec_x1, vec_y1, true);

		widget->addGraph();
		// 设置多边形的填充颜色
		widget->graph(widget->graphCount() - 1)->setBrush(QBrush(QColor(40, 80, 150)));  // Set the brush  if needed
		widget->graph(widget->graphCount() - 1)->setPen(QPen(Qt::green)); // 第一个图的线条颜色rgba(40, 80, 150)
		widget->graph(widget->graphCount() - 1)->setData(vec_x2, vec_y2, true);

		for (int i = 0; i < nameList.size(); i++)
		{
			// 创建一个文本项,显示标签
			QCPItemText *textLabel = new QCPItemText(widget);
			if (vec_x[i] > 0)
				textLabel->setPositionAlignment(Qt::AlignLeft | Qt::AlignBottom);
			else
				textLabel->setPositionAlignment(Qt::AlignRight | Qt::AlignBottom);
			textLabel->position->setCoords(vec_x[i], vec_y[i]); // 设置文本位置为线段的终点
			textLabel->setText(QString::number(vec_value[i])); // 设置文本内容
			textLabel->setFont(QFont("Aqency FB", 8)); // 设置文本字体
			textLabel->setColor(Qt::white);        //设置字体颜色
			 // 设置背景透明
			textLabel->setBrush(Qt::transparent); // 设置背景为透明
		}
	}
}

4、效果图如下

注:如果本文章对您有所帮助,请点赞收藏支持一下,谢谢。^_^

版权声明:本文为博主原创文章,转载请附上博文链接。

### 使用 QCustomPlot 绘制带箭头的线 QCustomPlot 是一个强大的 Qt C++ 形库,支持多种类型的绘制并提供了丰富的自定义选项。为了实现带有箭头效果的线条,在 QCustomPlot 中可以通过 `QCPItemLine` 和 `QCPItemStraightLine` 来创建直线,并通过设置其属性来添加箭头。 下面展示一段简单的例子代码,说明如何利用这些类在上画一条具有指向性的线段: ```cpp // 创建一个新的绘窗口实例 QCustomPlot *customPlot = new QCustomPlot(parent); // 添加一个直角坐标系到plot布局里 customPlot->addGraph(); customPlot->graph(0)->setLineStyle(QCPGraph::lsNone); // 不显示曲线本身 // 定义起点终点位置 double startX = 1, startY = 1; double endX = 4, endY = 5; // 插入一条新的直线项目至场景中 QCPItemLine *arrow = new QCPItemLine(customPlot); arrow->start->setCoords(startX, startY); // 设置起始点坐标 arrow->end->setCoords(endX, endY); // 设置结束点坐标 // 配置箭头样式 arrow->head->setVisible(true); // 显示头部(即箭头) arrow->tail->setVisible(false); // 关闭尾部装饰物 arrow->setHeadWidth(8); // 设定箭头宽度 arrow->setHeadLength(12); // 设定箭头长度 // 更新界面以反映更改 customPlot->replot(); // 将控件加入父级容器内以便可见 this->layout()->addWidget(customPlot); ``` 上述代码片段展示了基本的操作流程,具体参数可以根据实际需求调整。对于更详细的配置方法以及更多功能特性,请参阅官方文档[^1]获取最新最全的信息和支持材料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值