297 lines
9.2 KiB
C++
297 lines
9.2 KiB
C++
|
#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<int>() << 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<int>() << 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<chart_marker*>(sender()));
|
||
|
emit dataChanged(index(0, idx*2 + 2), index(rowCount() - 1, idx*2 + 1), QList<int>() << Qt::DisplayRole);
|
||
|
}
|
||
|
|
||
|
void chart_markers::series_data_changed()
|
||
|
{
|
||
|
int idx = index_of(static_cast<chart_series*>(sender()));
|
||
|
emit dataChanged(index(idx + 1, 0), index(idx + 1, columnCount() - 1), QList<int>() << Qt::DisplayRole);
|
||
|
}
|
||
|
}
|
||
|
}
|