#include "histogramchart.h" #include #include #include HistogramChart::HistogramChart(QQuickItem *parent) : QQuickPaintedItem(parent) { } void HistogramChart::paint(QPainter* painter) { const int leftPadding = 32; const int bottomPadding = 32; const int height = static_cast(this->height()); const int width = static_cast(this->width()); painter->fillRect(0, 0, width, height, Qt::white); if (_histogram.empty()) { return; } const qreal barHeight = height - bottomPadding; const qreal barWidth = (width - leftPadding) / static_cast(_histogram.size()); for (size_t i = 0; i < _histogram.size(); i++) { int count = _histogram[i]; qreal h = (count / static_cast(maxBinCount)) * barHeight; qreal x = i * barWidth; qreal y = barHeight - h; const QColor darkBlue = QColor::fromRgb(32, 74, 135); const QColor lightBlue = QColor::fromRgb(52, 101, 164); const QColor lighterBlue = QColor::fromRgb(114, 159, 207); QColor c = (lastUpdatedBinIndex == i) ? lighterBlue : lightBlue; QRectF barRect(x + leftPadding, y, barWidth, h); painter->fillRect(barRect, c); if (i % 10 == 0) { QRectF txtRect(x + leftPadding, barHeight, barWidth, 32); std::string str(16, '\0'); std::snprintf(&str[0], str.size(), "%g", minValue + i*_binWidth); painter->drawText(txtRect, Qt::AlignCenter | Qt::TextDontClip, QString::fromStdString(str)); } } } void HistogramChart::pushData(qreal value) { if(_histogram.empty()) { minValue = value; maxValue = value; _histogram.resize(1); } else if (value > maxValue) { int newMaxIndex = binIndex(value); Q_ASSERT(newMaxIndex >= 0); if (newMaxIndex > 0) { _histogram.resize(static_cast(newMaxIndex + 1)); } maxValue = value; } else if (value < minValue) { int oldMinIndex = binIndex(minValue); int newMinIndex = binIndex(value); int diff = oldMinIndex - newMinIndex; Q_ASSERT(diff > 0); _histogram.insert(_histogram.begin(), static_cast(diff), 0); minValue = value; } int idx = binIndex(value); int& count = _histogram.at(static_cast(idx)); count++; if (count >= maxBinCount) { maxBinCount = count; maxBinIndex = idx; } lastUpdatedBinIndex = static_cast(idx); stats.add(value); update(); } int HistogramChart::binIndex(qreal value) const { Q_ASSERT(!std::isnan(minValue)); return static_cast( std::floor( (value-minValue) / _binWidth)); } int HistogramChart::numberOfBins() const { Q_ASSERT(!std::isnan(minValue)); Q_ASSERT(!std::isnan(maxValue)); return static_cast( std::ceil((maxValue - minValue)/_binWidth) ); } void HistogramChart::clear() { std::fill(_histogram.begin(), _histogram.end(), 0); maxBinCount = 0; stats.clear(); } void HistogramChart::reset() { _histogram.resize(0); minValue = std::numeric_limits::quiet_NaN(); maxValue = std::numeric_limits::quiet_NaN(); maxBinCount = 0; stats.clear(); }