void PolColorMapChart::Init()
{
QVBoxLayout* layout = new QVBoxLayout(this);
m_customPlot = new QCustomPlot;
layout->addWidget(m_customPlot);
m_width = 16;
m_height = 8;
m_colorRange = 1000;
m_customPlot->xAxis->grid()->setPen(Qt::NoPen);
m_customPlot->yAxis->grid()->setPen(Qt::NoPen);
m_customPlot->xAxis->grid()->setSubGridVisible(false);
m_customPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
m_customPlot->yAxis->grid()->setSubGridVisible(true);
m_customPlot->yAxis->setPadding(5); // a bit more space to the left border
m_customPlot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
m_heatmap = new QCPColorMap(m_customPlot->xAxis, m_customPlot->yAxis); // 构造一个颜色图
changeChartSize();
QCPColorScale* colorScale = new QCPColorScale(m_customPlot); // 构造一个色条
colorScale->setType(QCPAxis::atRight); // 右侧垂直显示,与matlab版本一致
m_customPlot->plotLayout()->addElement(0, 1, colorScale); // 在颜色图右侧显示
m_heatmap->setColorScale(colorScale);
QCPColorGradient gradient; // 色条使用的颜色渐变
gradient.setColorStopAt(0.0, QColor("#0000ff")); // 设置色条开始时的颜色
gradient.setColorStopAt(0.5, QColor("#ffff00")); // 设置色条开始时的颜色
gradient.setColorStopAt(1.0, QColor("#ff0000")); // 设置色条结束时的颜色
m_heatmap->setGradient(gradient);
//colorMap->rescaleDataRange(); // 自动计算数据范围,数据范围决定了哪些数据值映射到QCPColorGradient的颜色渐变当中
m_heatmap->setInterpolate(false); // 为了显示小方块,我们禁用插值
setColorRange(m_colorRange);
// 保持色条与轴矩形边距一致
QCPMarginGroup* marginGroup = new QCPMarginGroup(m_customPlot);
m_customPlot->axisRect()->setMarginGroup(QCP::msLeft | QCP::msRight, marginGroup);
colorScale->setMarginGroup(QCP::msLeft | QCP::msRight, marginGroup);
//颜色图数据清空
//m_heatmap->data()->clear();
#if 0
//测试颜色图接口
setWidthHeight(16,8);
setColorRange(1000);
showColorForTest();
#endif
}
void PolColorMapChart::setWidthHeight(const int width, const int height)
{
m_width = width;
m_height = height;
changeChartSize();
}
void PolColorMapChart::setColorRange(const int colorRange)
{
m_colorRange = colorRange;
m_heatmap->setDataRange(QCPRange(0,m_colorRange));
}
void PolColorMapChart::changeChartSize()
{
m_heatmap->data()->setSize(m_width, m_height); // 设置颜色图数据维度,其内部维护着一个一维数组(一般表现为二维数组),这里可以理解为有多少个小方块
// 颜色图在x、y轴上的范围,这里的范围指的是以热力图一个像素点的中间,所以加上0.5就可以显示边缘部分的颜色,所以xy轴的范围也要+1
m_heatmap->data()->setRange(QCPRange(0.5,m_width + 0.5),QCPRange(0.5, m_height + 0.5));
m_customPlot->xAxis->setRange(0, m_width + 1);
m_customPlot->yAxis->setRange(0, m_height + 1);
m_customPlot->xAxis->ticker()->setTickCount(m_width + 1);
m_customPlot->yAxis->ticker()->setTickCount(m_height + 1);
m_customPlot->xAxis->setVisible(false);
m_customPlot->yAxis->setVisible(false);
}
void PolColorMapChart::addPoints(const QVector<int>& values)
{
if(values.size() != m_width * m_height)
{
return;
}
auto* colorMap = static_cast<QCPColorMap*>(m_customPlot->plottable(0));
int keySize = colorMap->data()->keySize();
int valueSize = colorMap->data()->valueSize();
for(int x = 0; x < keySize; ++x)
{
for(int y = 0; y < valueSize; ++y)
{
int index = x + y * keySize;
int colorValue = values.at(index);
colorMap->data()->setCell(x, valueSize - y - 1, colorValue);
}
}
m_customPlot->replot();
}
在热力图上 点上添加文本说明
首先初始化
QVector<QCPItemText*> m_vTextItem;
void PolColorMapChart::changeChartSize()
{
m_heatmap->data()->setSize(m_width, m_height); // 设置颜色图数据维度,其内部维护着一个一维数组(一般表现为二维数组),这里可以理解为有多少个小方块
// 颜色图在x、y轴上的范围,这里的范围指的是以热力图一个像素点的中间,所以加上0.5就可以显示边缘部分的颜色,所以xy轴的范围也要+1
m_heatmap->data()->setRange(QCPRange(0.5, m_width + 0.5), QCPRange(0.5, m_height + 0.5));
m_customPlot->xAxis->setRange(0, m_width + 1);
m_customPlot->yAxis->setRange(0, m_height + 1);
m_customPlot->xAxis->ticker()->setTickCount(m_width + 1);
m_customPlot->yAxis->ticker()->setTickCount(m_height + 1);
m_customPlot->xAxis->setVisible(false);
m_customPlot->yAxis->setVisible(false);
int itemSize = m_vTextItem.size();
for(int i = 0; i < itemSize; i++)
{
if(m_vTextItem.at(i))
{
m_vTextItem.at(i)->deleteLater();
}
}
m_vTextItem.clear();
for(int i = 0; i < m_width * m_height; i++)
{
QCPItemText* textItem = new QCPItemText(m_customPlot);
m_vTextItem.append(textItem);
}
}
添加热力图点时 设置QCPItemText的位置和内容
void PolColorMapChart::addPoints(const QVector<int>& values)
{
if(values.size() != m_width * m_height)
{
return;
}
auto* colorMap = static_cast<QCPColorMap*>(m_customPlot->plottable(0));
int keySize = colorMap->data()->keySize();
int valueSize = colorMap->data()->valueSize();
for(int x = 0; x < keySize; ++x)
{
for(int y = 0; y < valueSize; ++y)
{
int index = x + y * keySize;
int colorValue = values.at(index);
colorMap->data()->setCell(x, valueSize - y - 1, colorValue);
double coorX;
double coorY;
colorMap->data()->cellToCoord(x, valueSize - y - 1, &coorX, &coorY);
QCPItemText* textItem = m_vTextItem[index];
int row = index / m_width + 1;
int col = index % m_width + 1;
textItem->setText("row:" + QString::number(row) + "\n" +
"col:" + QString::number(col) + "\n" +
QString::number(colorValue)
);
textItem->setPositionAlignment(Qt::AlignCenter | Qt::AlignVCenter);
textItem->setColor(Qt::black);
textItem->position->setCoords(coorX, coorY);
}
}
m_customPlot->replot();
}