1 #include "heatmapview.h"
8 HeatmapView::HeatmapView(QWidget* parent) :
13 setMouseTracking(true);
17 void HeatmapView::setDataProvider(HeatmapDataProvider* data)
23 m_data->setSelectionState(m_selectionState);
25 setDefaultView(m_data->start(), m_data->end());
27 m_viewWidthMin = 1000;
30 m_graphTop = (m_data->headerRows() + m_data->dataRows()) * m_rowHeight;
33 m_graphBottom = m_graphTop = 0;
40 void HeatmapView::setSelectionState(SelectionState* state)
43 m_data->setSelectionState(state);
46 GraphView::setSelectionState(state);
50 void HeatmapView::mouseMoveEvent(QMouseEvent *e)
52 GraphView::mouseMoveEvent(e);
54 if (e->buttons() || !m_data) {
59 qint64 index = itemAtPosition(e->pos());
62 QToolTip::showText(e->globalPos(), m_data->itemTooltip(index));
69 void HeatmapView::mouseDoubleClickEvent(QMouseEvent *e)
71 if (m_data && e->button() == Qt::LeftButton) {
72 qint64 index = itemAtPosition(e->pos());
75 m_data->itemDoubleClicked(index);
80 GraphView::mouseDoubleClickEvent(e);
84 void HeatmapView::paintEvent(QPaintEvent *)
90 QPainter painter(this);
91 painter.fillRect(0, m_data->headerRows() * m_rowHeight, width(), height(), Qt::white);
94 painter.translate(0, m_data->headerRows() * m_rowHeight - m_viewBottom % m_rowHeight);
95 int rowStart = m_viewBottom / m_rowHeight;
96 int rowEnd = qMin<int>(qCeil(m_viewTop / (double)m_rowHeight), m_data->dataRows());
98 for (unsigned i = rowStart; i < rowEnd; ++i) {
99 HeatmapRowIterator* itr = m_data->dataRowIterator(i, m_viewLeft, m_viewRight, width());
100 paintRow(painter, itr);
101 painter.translate(0, m_rowHeight);
106 painter.resetTransform();
107 painter.fillRect(0, 0, width(), m_data->headerRows() * m_rowHeight, Qt::white);
109 for (unsigned i = 0; i < m_data->headerRows(); ++i) {
110 HeatmapRowIterator* itr = m_data->headerRowIterator(i, m_viewLeft, m_viewRight, width());
111 paintRow(painter, itr);
112 painter.translate(0, m_rowHeight);
116 /* Draw Axis Lines */
117 painter.resetTransform();
118 painter.setPen(Qt::black);
119 painter.drawLine(0, m_rowHeight, width(), m_rowHeight);
120 painter.drawLine(0, m_rowHeight * 2, width(), m_rowHeight * 2);
122 painter.setPen(QColor(240, 240, 240));
123 painter.translate(0, m_data->headerRows() * m_rowHeight - m_viewBottom % m_rowHeight);
125 for (unsigned i = rowStart; i < rowEnd; ++i) {
126 painter.drawLine(0, m_rowHeight, width(), m_rowHeight);
127 painter.translate(0, m_rowHeight);
130 /* Draw selection borders */
131 painter.resetTransform();
132 painter.setPen(Qt::green);
134 if (m_selectionState->type == SelectionState::Horizontal) {
135 double dxdt = width() / (double)m_viewWidth;
136 double scroll = m_viewLeft * dxdt;
137 double left = (m_selectionState->start * dxdt) - scroll;
138 double right = (m_selectionState->end * dxdt) - scroll;
141 if (left >= 0 && left <= width()) {
142 painter.drawLine(left, 0, left, height());
145 if (right >= 0 && right <= width()) {
146 painter.drawLine(right, 0, right, height());
148 } else if (m_selectionState->type == SelectionState::Vertical) {
150 int row = m_selectionState->start;
152 for (unsigned i = rowStart; i < rowEnd; ++i) {
153 if (m_data->dataRowAt(i) == row) {
156 painter.translate(0, m_data->headerRows() * m_rowHeight - m_viewBottom % m_rowHeight);
157 painter.drawLine(0, (row + 1) * m_rowHeight, width(), (row + 1) * m_rowHeight);
160 painter.drawLine(0, row * m_rowHeight, width(), row * m_rowHeight);
170 void HeatmapView::paintRow(QPainter& painter, HeatmapRowIterator* itr)
172 bool selection = m_selectionState ? m_selectionState->type != SelectionState::None : false;
176 double heat = itr->heat();
177 int width = itr->width();
180 /* Gamma correction */
181 heat = qPow(heat, 1.0 / 2.0);
184 /* Draw single line */
186 double selectedHeat = itr->selectedHeat();
188 if (selectedHeat >= 0.999) {
189 heat = 255.0 - qBound(0.0, heat * 255.0, 255.0);
192 painter.setPen(QColor(255, heat, heat));
194 painter.setPen(QColor(heat, heat, 255));
197 painter.drawLine(x, 0, x, m_rowHeight - 1);
199 heat = 255.0 - qBound(0.0, heat * 100.0, 100.0);
200 painter.setPen(QColor(heat, heat, heat));
201 painter.drawLine(x, 0, x, m_rowHeight - 1);
203 if (selectedHeat > 0.001) {
204 selectedHeat = qPow(selectedHeat, 1.0 / 2.0);
205 selectedHeat = qBound(0.0, selectedHeat * 255.0, 255.0);
208 painter.setPen(QColor(255, 0, 0, selectedHeat));
210 painter.setPen(QColor(0, 0, 255, selectedHeat));
213 painter.drawLine(x, 0, x, m_rowHeight - 1);
217 heat = qBound(0.0, heat * 255.0, 255.0);
220 painter.setPen(QColor(255, 255 - heat, 255 - heat));
222 painter.setPen(QColor(255 - heat, 255 - heat, 255));
225 painter.drawLine(x, 0, x, m_rowHeight - 1);
228 double selectedHeat = itr->selectedHeat();
230 if (selection && selectedHeat < 0.9) {
231 painter.fillRect(x, 0, width, m_rowHeight, QColor(255 - 100, 255 - 100, 255 - 100));
232 } else if (itr->isGpu()) {
233 painter.fillRect(x, 0, width, m_rowHeight, QColor(255, 0, 0));
235 painter.fillRect(x, 0, width, m_rowHeight, QColor(0, 0, 255));
239 painter.setPen(Qt::white);
240 QString elided = painter.fontMetrics().elidedText(itr->label(), Qt::ElideRight, width - 1);
242 painter.drawText(x + 1, 0, width - 1, m_rowHeight - 1,
243 Qt::AlignLeft | Qt::AlignVCenter,
251 qint64 HeatmapView::itemAtPosition(QPoint pos)
257 double t = m_viewWidth / (double)width();
261 qint64 time = (qint64)t;
264 if (pos.y() < m_data->headerRows() * m_rowHeight) {
265 int row = pos.y() / m_rowHeight;
266 index = m_data->headerItemAt(row, time);
269 row -= m_data->headerRows() * m_rowHeight;
272 index = m_data->dataItemAt(row, time);