由于项目中遇到饼图各个切片重合的情况,虽然可以通过设置透明度进行颜色融合,但仍然不能满足需求,思考再三,想出普通饼图+环形外框的方案,大家一起来看看效果吧!
关键代码如下:
void PiePanel::initViewData(QPainter *painter)
{
int border_width = 1;
QString label_str = partitionPieInfo_.name;
QFont font = painter->font();
font.setPixelSize(TITLE_PIXEL_SIZE);
// font.setBold(true);
QFontMetrics fm(font);
int pixelsWide = fm.width(label_str);
int pixelsHigh = fm.height();
//! draw header
painter->save();
QPen pen(Qt::black, border_width);
pen.setStyle(Qt::DashLine);
painter->setFont(font);
painter->setPen(pen);
painter->drawText(QPoint(2, pixelsHigh), label_str); // (this->width()-pixelsWide)/2
painter->restore();
//!重叠
QMap<QString, QPair<int, int> > overlayMap; // 名称, offset; 宽度
painter->save();
painter->setRenderHints(QPainter::Antialiasing);
QMap<double,QString> degreeMap;
int offset_ = 1;
all_labels_map_.clear();
for(auto partitionInfo:partitionPieInfo_.partitionInfoContainer)
{
double startDegree = -(partitionInfo.startTime/partitionPieInfo_.allTime*360)+90;//开始角度
double endDegree = startDegree-(partitionInfo.durationTime/partitionPieInfo_.allTime*360);//结束角度
//获取周期单位下的开始时间
TimeValue startTime(partitionInfo.startTime,TimeUnit::Nanosecond);
double startTimeValue = startTime.getValueWithUnit(partitionPieInfo_.unit);
QString startTimeStr = QString::number(startTimeValue) + UNIT_STR_MAP.value(partitionPieInfo_.unit);
//获取周期单位下的结束时间
TimeValue endTime(partitionInfo.startTime+partitionInfo.durationTime,TimeUnit::Nanosecond);
double endTimeValue = endTime.getValueWithUnit(partitionPieInfo_.unit);
QString endTimeStr = QString::number(endTimeValue) + UNIT_STR_MAP.value(partitionPieInfo_.unit);
//记录所有开始和结束数据
degreeMap.insert(startDegree,startTimeStr);
degreeMap.insert(endDegree,endTimeStr);
int partitionstartAngle = startDegree;
int partitionspanAngle = -(partitionInfo.durationTime/partitionPieInfo_.allTime*360);
//配置分区信息
PieFrameInfo pieFrameInfo;
pieFrameInfo.name = partitionInfo.name;
pieFrameInfo.startTime = startTimeStr;
pieFrameInfo.endTime = endTimeStr;
outCount = partitionInfo.taskInfoContainer.count();
for(auto task:partitionInfo.taskInfoContainer)
{
//获取周期单位下的开始时间
TimeValue taskStartTime(task.startTime,TimeUnit::Nanosecond);
double taskStartTimeValue = taskStartTime.getValueWithUnit(partitionPieInfo_.unit);
QString taskStartTimeStr = QString::number(taskStartTimeValue) + UNIT_STR_MAP.value(partitionPieInfo_.unit);
//获取周期单位下的结束时间
TimeValue taskEndTime(task.startTime+task.durationTime,TimeUnit::Nanosecond);
double taskEndTimeValue = taskEndTime.getValueWithUnit(partitionPieInfo_.unit);
QString taskEndTimeStr = QString::number(taskEndTimeValue) + UNIT_STR_MAP.value(partitionPieInfo_.unit);
//配置任务信息
PieInfo pieInfo;
pieInfo.name = task.name;
pieInfo.startTime = taskStartTimeStr;
pieInfo.endTime = taskEndTimeStr;
//角度
int startAngle = -(task.startTime/partitionPieInfo_.allTime*360)+90;//开始角度
int spanAngle = -(task.durationTime/partitionPieInfo_.allTime*360);//跨越角度
//设置alpha
QColor tmpColor = task.pieColor;
tmpColor.setAlpha(100);
QString childLabelStr = tr("%1(%2~%3)").arg(pieInfo.name).arg(pieInfo.startTime).arg(pieInfo.endTime);
QFont font = painter->font();
font.setPixelSize(10);
QFontMetrics fm(font);
int font_width = fm.width(childLabelStr)+5;
QString tmpKey = tr("%1,%2").arg(startAngle).arg(spanAngle);
if(overlayMap.contains(tmpKey))
{
overlayMap[tmpKey] = qMakePair(overlayMap[tmpKey].first + 1, overlayMap[tmpKey].second + font_width);
}
else
{
overlayMap[tmpKey] = qMakePair(1, font_width);
}
drawPie(painter, startAngle*16, spanAngle*16, tmpColor, childLabelStr, offset_ ++, overlayMap[tmpKey]);
}
drawBorder(painter,partitionstartAngle*16,partitionspanAngle*16);
}
//! 分区外框虚线的起始时间&结束时间
QMap<double, int> ready_draw_map;//whp add 2021-11-10,两个文本如果y值重合,那么就进行上移操作。
QList<double> keyList = degreeMap.keys();//获取需要绘制文本的角度
for(auto degree:keyList){
QString text = degreeMap.value(degree);
QFontMetrics fm(this->font());
int pixelsWide = fm.width(text);
int pixelsHigh = fm.height();
float radians = qDegreesToRadians(degree);
int x_center = this->width() / 2;
int y_center = this->height() * CENTER_OFFSET_PERCENT;
int x = (radius_ + BORDER_TEXT_OFFSET)*(qCos(radians));
int y = (radius_ + BORDER_TEXT_OFFSET)*(-qSin(radians));
textTransformation(x,y,pixelsWide,pixelsHigh);
if(ready_draw_map.contains(y))
{
int value = ready_draw_map[y];
ready_draw_map[y] = value + 1;
y = y + value * 10;
}
else
{
ready_draw_map.insert(y, 1);
}
x = x + x_center;
y = y + y_center - pixelsHigh;
QFont font = painter->font();
font.setPixelSize(SCALE_PIXEL_SIZE);
painter->setFont(font);
painter->drawText(QRect(x,y,pixelsWide,pixelsHigh),text);
}
painter->restore();
}
全套代码链接:🍞正在为您运送作品详情