IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> QPieSeries QPieSlice label 标签重叠解决方案 -> 正文阅读

[游戏开发]QPieSeries QPieSlice label 标签重叠解决方案

demo 下载地址在最后


通常我们在用QPieSeries 做饼状图,并且饼状图几个部分差别不太大时,label 标签展示都是正常的,期望如下图:

一般情况下做这种饼状图很简单,如:

    QPieSeries *series = new QPieSeries(this);
    series->append("迟到人数22", 22);
    series->append("旷工人数35", 35);
    series->append("正常出勤人数97", 97);
    series->setLabelsVisible();

    QPieSlice *slice1 = series->slices().at(0);
    QPieSlice *slice2 = series->slices().at(1);
    QPieSlice *slice3 = series->slices().at(2);
    slice1->setColor(QColor(79, 129, 189));
    slice2->setColor(QColor(192, 80, 77));
    slice3->setColor(QColor(155, 187, 89));

    QChart *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("PieChart");
    chart->legend()->hide();

    QChartView *chartview = new QChartView(chart);
    chartview->setRenderHint(QPainter::Antialiasing);
    ui->widget->layout()->addWidget(chartview);

?我们展示了三个标签,数据分别是22, 35 和 97,label 展示的也都正常。但是有一种情况,就是当其中两个数据很小时,会出现标签label 重叠的问题,例如我们将pie的三组数据分别更改为 1, 2 和 97时,就会label就会重叠:

?这显然不是我们想要的。但是怎么样才能避免这种标签重叠的现象呢?其实原理很简单,出现这种情况的原因有两个:

1. 相邻的两个slice 块数值(比例)都很小;

2. 这两个slice?块都在起始角度的一侧;

第二点就是我们要解决这种情况的切入点。?

因为添加? slice 的顺序就是从起始角度开始展示的顺序,例如上面错误的图我们添加的顺序就是小,小,大的顺序,也就是从起始角度(12点钟方向开始顺时针添加),结果就会造成上面的现象。

    QPieSeries *series = new QPieSeries(this);
    series->append("迟到人数1", 1);
    series->append("旷工人数2", 2);
    series->append("正常出勤人数97", 97);

那么我们添加两个最小的 slice 分别显示在起始角度的两侧,那么添加顺序就应该是 小、大、小了,也就是优化一下添加顺序, 就能得出让我们满意的结果。

    series->append("迟到人数1", 1);
    series->append("正常出勤人数97", 97);
    series->append("旷工人数2", 2);

两个新的问题:

1.? 局限性:slice的个数不是固定的且每个slice 的大小是会变化的,我们不能写死数据。

2.? 每个 slice 颜色是不固定的,最小的永远都是蓝色,最大的永远都是红色...

解决方案:

?我们要解决上面的问题,就要写成一个通用的控件,如果有n个slice,我们就需要对每个slice 按照 数值大小进行排成 : “小-大-小-大...” 的顺序。

如果对每个slice有固定颜色的需求(例如,出勤人数使用绿色,缺勤人数使用红色),我们需要将颜色与slice 进行绑定,没有此需求的可以略过。为做成通用类型,我们slice 绑定固定的颜色。

所以,我们需要将每个slice 信息封装成一个结构体 SliceInfo:

struct SliceInfo{
    int     m_value;        // 数值
    QString m_labelName;    // label 标签
    QColor  m_color;        // 颜色

    SliceInfo(int value, QString name, QColor color) {
        m_value = value;
        m_labelName = name;
        m_color = color;
    }
};

所以,对于n个slice ,我们需要封装一个方法,能够根据 n个SliceInfo 创建排好序的 n个 QPieSlice 对象。然后我们只需要将获取的QPieslice 对象依次添加到 QPieSeries 中即可:

QList<QPieSlice*> MainWindow::sortPie(QList<SliceInfo> &slicesInfo)
{
    // 1. 排序 value "小大小大"  的顺序排列
    QList<SliceInfo> sortSliceInfo;
    bool bMin  = true;
    int count = slicesInfo.size();
    for (int i = 0; i < count; i++) {
        int index = 0;
        for (int j = 1; j < slicesInfo.size(); j++) {
            if (bMin) { // 取最小数
                if (slicesInfo.at(index).m_value > slicesInfo.at(j).m_value) {
                    index = j;
                }
            } else { // 取最大数
                if (slicesInfo.at(index).m_value < slicesInfo.at(j).m_value) {
                    index = j;
                }
            }
        }

        SliceInfo info = slicesInfo.takeAt(index);
        sortSliceInfo.append(info);

        // 交替取大小数
        bMin = !bMin;
    }

    // 2. 创建
    QList<QPieSlice*> slices;
    for (int i = 0; i < sortSliceInfo.size(); i++) {
        QPieSlice *pieSlice = new QPieSlice(sortSliceInfo.at(i).m_labelName, sortSliceInfo.at(i).m_value);
        pieSlice->setColor(sortSliceInfo.at(i).m_color);
        slices.append(pieSlice);
    }

    return slices;
}

这样,我们就可以在获取信息后进行创建一系列排好序的slice了

    QList<SliceInfo> piesInfo;
    piesInfo.append(SliceInfo(1, "迟到人数1", QColor(79, 129, 189)));
    piesInfo.append(SliceInfo(2, "旷工人数2", QColor(192, 80, 77)));
    piesInfo.append(SliceInfo(97, "正常出勤人数97", QColor(155, 187, 89)));

    // 排序
    QList<QPieSlice*> pies = sortPie(piesInfo);

    QPieSeries *series = new QPieSeries(this);
    for (int i = 0; i < pies.size(); i++) {
        series->append(pies.at(i));
    }

?这样我们就用一个通用的方法来解决了QPieSeries QPieSlice label 标签重叠的问题。

demo 免费下载地址 :QT_QPieSeries_QPieSlicelabel标签重叠解决方案-QT文档类资源-CSDN下载QtQPieSeriesQPieSlicelabel标签重叠解决方案详细介绍请参见博客:更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/xiezhongyuan07/85227152

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-28 12:10:15  更:2022-04-28 12:11:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:47:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码