#include "seriesmodel.h" // cpp // tbb #ifdef __linux__ #ifndef Q_MOC_RUN #if defined(emit) #undef emit #include #define emit // restore the macro definition of "emit", as it was defined in // gtmetamacros.h #else #include #endif // defined(emit) #endif // Q_MOC_RUN #endif SeriesModel::SeriesModel(QObject* parent) : QAbstractTableModel(parent) { } SeriesModel::SeriesModel(const SeriesModel& other) : QAbstractTableModel() { append(other.m_points); } int SeriesModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent); return m_points.count(); } int SeriesModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent); return 2; } QVariant SeriesModel::data(const QModelIndex& modelIndex, int role) const { if (!modelIndex.isValid()) return QVariant(); if (modelIndex.row() < 0 || modelIndex.row() >= m_points.count()) return QVariant(); if (role == Qt::DisplayRole) { if (modelIndex.column() == 0) return m_points.at(modelIndex.row()).x(); else if (modelIndex.column() == 1) return m_points.at(modelIndex.row()).y(); } return QVariant(); } void SeriesModel::append(const QVector points) { QMutexLocker l(&m_mtx); beginInsertRows( QModelIndex(), m_points.count(), m_points.count() + points.count() - 1 ); m_points << points; endInsertRows(); recalcLimits(); } void SeriesModel::clear() { QMutexLocker l(&m_mtx); if (m_points.isEmpty()) return; beginRemoveRows(QModelIndex(), 0, m_points.count() - 1); m_points.clear(); endRemoveRows(); } void SeriesModel::recalcLimits() { // WARNING: not thread safe m_minX = std::numeric_limits::max(); m_maxX = std::numeric_limits::min(); m_minY = std::numeric_limits::max(); m_maxY = std::numeric_limits::min(); #ifdef __linux__ const auto [minX, maxX] = std::minmax_element( std::execution::par_unseq, m_points.constBegin(), m_points.constEnd(), [](const auto& a, const auto& b) { return a.x() < b.x(); } ); const auto [minY, maxY] = std::minmax_element( std::execution::par_unseq, m_points.constBegin(), m_points.constEnd(), [](const auto& a, const auto& b) { return a.y() < b.y(); } ); float min = std::min(minX->x(), minY->y()); float max = std::max(maxX->x(), maxY->y()); #else for (const auto& p : m_points) { if (p.x() < m_minX) m_minX = p.x(); if (p.x() > m_maxX) m_maxX = p.x(); if (p.y() < m_minY) m_minY = p.y(); if (p.y() > m_maxY) m_maxY = p.y(); } float min = std::min(m_minX, m_minY); float max = std::max(m_maxX, m_maxY); #endif m_minX = min; m_maxX = max; m_minY = min; m_maxY = max; emit minXChanged(); emit maxXChanged(); emit minYChanged(); emit maxYChanged(); } void SeriesModel::replace(const QVector points) { clear(); append(points); }