#include "gtl_gui_chart_markers.h" namespace gtl { namespace gui { class markers_cmp { public: bool operator()(chart_marker* m0, chart_marker* m1) const { return m0->pos() < m1->pos(); } }; chart_markers::chart_markers(QObject *parent) : QAbstractTableModel(parent) , _color(Qt::black) , _bgnd_color(Qt::white) { } QVariant chart_markers::headerData(int section, Qt::Orientation orientation, int role) const { if(role == Qt::DisplayRole) { if(orientation == Qt::Vertical) { if(section == 0) return ""; else return _series[section - 1]->name(); } else { return 1; } } else if (role == Qt::BackgroundRole) { return QVariant(QBrush(/*Qt::white*/_bgnd_color)); } else if (role == Qt::ForegroundRole) { if (section == 0) return QVariant(QBrush(/*Qt::black*/_color)); else return QVariant(QBrush(_series[section - 1]->color())); } return QVariant(); } int chart_markers::rowCount(const QModelIndex &/*parent*/) const { return _series.size() + 1; } int chart_markers::columnCount(const QModelIndex &/*parent*/) const { return _markers.size()*2 + 1; } QVariant chart_markers::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if(role == Qt::DisplayRole) { if (index.column() == 0) return index.row() == 0 ? "x" : "y"; if (index.column() % 2 == 1) { if(index.row() != 0) return QVariant(QString::number(index.column() / 2 + 1)); } else if (index.row() == 0) return QVariant(QString::number(_markers[(index.column() - 1) / 2]->pos(), 'f', 3)); else { qreal value = _markers[(index.column() - 1) / 2]->value(index.row() - 1); return qIsNaN(value) ? "-" : QString::number(value, 'f', 6); } } else if (role == Qt::BackgroundRole) { return QVariant(QBrush(/*Qt::white*/_bgnd_color)); } else if (role == Qt::ForegroundRole) { if (index.row() == 0) if (index.column() == 0) return QVariant(QBrush(/*Qt::black*/_color)); else return QVariant(QBrush(/*Qt::black*//*_color*/_markers[(index.column() - 1) / 2]->color())); else if(index.column() % 2 == 1) return QVariant(QBrush(/*Qt::black*//*_color*/_markers[(index.column() - 1) / 2]->color())); else return QVariant(QBrush(_series[index.row() - 1]->color())); } else if (role == Qt::TextAlignmentRole) return QVariant(Qt::AlignCenter); else if (role == Qt::DecorationRole) { if (index.column() % 2 == 1) { if(index.row() == 0) { if(QString(_markers[(index.column() - 1) / 2]->metaObject()->className()).contains("chart_marker")) return QVariant(QPixmap(":chart/single_marker")); else if(QString(_markers[(index.column() - 1) / 2]->metaObject()->className()).contains("band_marker")) return QVariant(QPixmap(":chart/band_marker")); else if(QString(_markers[(index.column() - 1) / 2]->metaObject()->className()).contains("harm_marker")) return QVariant(QPixmap(":chart/harm_marker")); } } } /* else if (role == Qt::SizeHintRole) { if (index.column() % 2 == 1) { if(index.row() == 0) return QVariant(QSize(10, 10)); } } */ return QVariant(); } void chart_markers::add_marker(chart_marker *marker) { // marker->set_color(_color); beginInsertColumns(QModelIndex(), (int)_markers.size(), (int)_markers.size() + 1); _markers.push_back(marker); endInsertColumns(); connect(marker, &chart_marker::position_changed, this, &chart_markers::marker_position_changed); connect(marker, &chart_marker::idx_changed, this, &chart_markers::marker_position_changed); sort_markers(); } void chart_markers::remove_marker(chart_marker *marker) { int idx = index_of(marker); beginRemoveColumns(QModelIndex(), idx*2 + 1, idx*2 + 2); _markers.erase(_markers.begin() + idx); endRemoveColumns(); sort_markers(); } void chart_markers::add_series(chart_series *series) { beginInsertRows(QModelIndex(), (int)_series.size() + 1, (int)_series.size() + 1); _series.push_back(series); endInsertRows(); connect(series, &chart_series::data_changed, this, &chart_markers::series_data_changed); if(_series.size() == 1) { foreach(chart_marker* marker, _markers) marker->set_pos(); } } void chart_markers::remove_series(chart_series *series) { int idx = index_of(series); beginRemoveRows(QModelIndex(), idx + 1, idx + 1); _series.erase(_series.begin() + idx); endRemoveRows(); } chart_marker *chart_markers::marker_at(const QPointF &point) const { foreach(chart_marker* marker, _markers) { if(marker->contains(point)) return marker; } return NULL; } int chart_markers::count_markers() const { return (int)_markers.size(); } chart_marker *chart_markers::marker(int idx) const { return _markers[idx]; } void chart_markers::set_color(QColor color) { // for(auto marker: _markers) // marker->set_color(color); _color = color; emit color_changed(); emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1), QList() << Qt::ForegroundRole); } QColor chart_markers::color() const { return _color; } void chart_markers::set_bgnd_color(QColor color) { _bgnd_color = color; emit color_changed(); emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1), QList() << Qt::ForegroundRole); } QColor chart_markers::bgnd_color() const { return _bgnd_color; } QVariant chart_markers::get_marker_value(int idx_marker, int idx_series) const { if(_series[idx_series]->size() < 2) return QVariant("-"); qreal x = _markers[idx_marker]->pos(); auto it = std::lower_bound(_series[idx_series]->begin_data(), _series[idx_series]->end_data(), QPointF(x, 0), []( const QPointF &p0, const QPointF &p1) { return p0.x() < p1.x(); } ); if(it->x() == x) return QString::number(it->y(), 'f', 6); return QVariant("-"); } int chart_markers::index_of(chart_marker *marker) const { return std::find(_markers.begin(), _markers.end(), marker) - _markers.begin(); } int chart_markers::index_of(chart_series *series) const { return std::find(_series.begin(), _series.end(), series) - _series.begin(); } void chart_markers::sort_markers() { std::sort(_markers.begin(), _markers.end(), markers_cmp()); for(int i = 0; i < _markers.size(); i++) _markers[i]->set_idx(i); } void chart_markers::marker_position_changed() { sort_markers(); int idx = index_of(static_cast(sender())); emit dataChanged(index(0, idx*2 + 2), index(rowCount() - 1, idx*2 + 1), QList() << Qt::DisplayRole); } void chart_markers::series_data_changed() { int idx = index_of(static_cast(sender())); emit dataChanged(index(idx + 1, 0), index(idx + 1, columnCount() - 1), QList() << Qt::DisplayRole); } } }