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、效果图如下
注:如果本文章对您有所帮助,请点赞收藏支持一下,谢谢。^_^
版权声明:本文为博主原创文章,转载请附上博文链接。