Commit 78620bd1 authored by Gus Grubba's avatar Gus Grubba Committed by Lorenz Meier

WIP - Arbitrary number of dimensions.

parent 5c4a5821
...@@ -18,14 +18,6 @@ QT_CHARTS_USE_NAMESPACE ...@@ -18,14 +18,6 @@ QT_CHARTS_USE_NAMESPACE
Q_DECLARE_METATYPE(QAbstractSeries*) Q_DECLARE_METATYPE(QAbstractSeries*)
//-----------------------------------------------------------------------------
QGCMAVLinkMessageField::Range_st::Range_st(QObject* parent, const QString& l, qreal r)
: QObject(parent)
, label(l)
, range(r)
{
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QGCMAVLinkMessageField::QGCMAVLinkMessageField(QGCMAVLinkMessage *parent, QString name, QString type) QGCMAVLinkMessageField::QGCMAVLinkMessageField(QGCMAVLinkMessage *parent, QString name, QString type)
: QObject(parent) : QObject(parent)
...@@ -34,46 +26,35 @@ QGCMAVLinkMessageField::QGCMAVLinkMessageField(QGCMAVLinkMessage *parent, QStrin ...@@ -34,46 +26,35 @@ QGCMAVLinkMessageField::QGCMAVLinkMessageField(QGCMAVLinkMessage *parent, QStrin
, _msg(parent) , _msg(parent)
{ {
qCDebug(MAVLinkInspectorLog) << "Field:" << name << type; qCDebug(MAVLinkInspectorLog) << "Field:" << name << type;
_rangeSt.append(new Range_st(this, tr("Auto"), 0));
_rangeSt.append(new Range_st(this, tr("10,000"), 10000));
_rangeSt.append(new Range_st(this, tr("1,000"), 1000));
_rangeSt.append(new Range_st(this, tr("100"), 100));
_rangeSt.append(new Range_st(this, tr("10"), 10));
_rangeSt.append(new Range_st(this, tr("1"), 1));
_rangeSt.append(new Range_st(this, tr("0.1"), 0.1));
_rangeSt.append(new Range_st(this, tr("0.01"), 0.01));
_rangeSt.append(new Range_st(this, tr("0.001"), 0.001));
_rangeSt.append(new Range_st(this, tr("0.0001"), 0.0001));
emit rangeListChanged();
} }
//---------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QStringList void
QGCMAVLinkMessageField::rangeList() QGCMAVLinkMessageField::addSeries(QAbstractSeries* series, bool left)
{ {
if(!_rangeList.count()) { if(!_pSeries) {
for(int i = 0; i < _rangeSt.count(); i++) { _left = left;
_rangeList << _rangeSt[i]->label; _pSeries = series;
} emit seriesChanged();
_dataIndex = 0;
_msg->msgCtl()->addChartField(this, left);
_msg->select();
} }
return _rangeList;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
QGCMAVLinkMessageField::setRange(quint32 r) QGCMAVLinkMessageField::delSeries()
{ {
if(r < static_cast<quint32>(_rangeSt.count())) { if(_pSeries) {
_rangeIndex = r; _values.clear();
_range = _rangeSt[static_cast<int>(r)]->range; _msg->msgCtl()->delChartField(this, _left);
emit rangeChanged(); QLineSeries* lineSeries = static_cast<QLineSeries*>(_pSeries);
//-- If not Auto, use defined range lineSeries->replace(_values);
if(_rangeIndex > 0) { _pSeries = nullptr;
_rangeMin = -_range; _left = false;
emit rangeMinChanged(); emit seriesChanged();
_rangeMax = _range; _msg->select();
emit rangeMaxChanged();
}
} }
} }
...@@ -81,6 +62,7 @@ QGCMAVLinkMessageField::setRange(quint32 r) ...@@ -81,6 +62,7 @@ QGCMAVLinkMessageField::setRange(quint32 r)
QString QString
QGCMAVLinkMessageField::label() QGCMAVLinkMessageField::label()
{ {
//-- Label is message name + field name
return QString(_msg->name() + ": " + _name); return QString(_msg->name() + ": " + _name);
} }
...@@ -94,29 +76,6 @@ QGCMAVLinkMessageField::setSelectable(bool sel) ...@@ -94,29 +76,6 @@ QGCMAVLinkMessageField::setSelectable(bool sel)
} }
} }
//-----------------------------------------------------------------------------
void
QGCMAVLinkMessageField::setSelected(bool sel)
{
if(_selected != sel) {
_selected = sel;
emit selectedChanged();
_values.clear();
_times.clear();
_rangeMin = 0;
_rangeMax = 0;
_dataIndex = 0;
emit rangeMinChanged();
emit rangeMaxChanged();
if(_selected) {
_msg->msgCtl()->addChartField(this);
} else {
_msg->msgCtl()->delChartField(this);
}
_msg->select();
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
QGCMAVLinkMessageField::updateValue(QString newValue, qreal v) QGCMAVLinkMessageField::updateValue(QString newValue, qreal v)
...@@ -125,34 +84,38 @@ QGCMAVLinkMessageField::updateValue(QString newValue, qreal v) ...@@ -125,34 +84,38 @@ QGCMAVLinkMessageField::updateValue(QString newValue, qreal v)
_value = newValue; _value = newValue;
emit valueChanged(); emit valueChanged();
} }
if(_selected) { if(_pSeries) {
int count = _values.count(); int count = _values.count();
//-- Arbitrary limit of 1 minute of data at 50Hz for now //-- Arbitrary limit of 1 minute of data at 50Hz for now
if(count < (50 * 60)) { if(count < (50 * 60)) {
_values.append(v); QPointF p(QGC::groundTimeMilliseconds(), v);
_times.append(QGC::groundTimeMilliseconds()); _values.append(p);
} else { } else {
if(_dataIndex >= count) _dataIndex = 0; if(_dataIndex >= count) _dataIndex = 0;
_values[_dataIndex] = v; _values[_dataIndex].setX(QGC::groundTimeMilliseconds());
_times[_dataIndex] = QGC::groundTimeMilliseconds(); _values[_dataIndex].setY(v);
_dataIndex++; _dataIndex++;
} }
//-- Auto Range //-- Auto Range
if(_rangeIndex == 0) { if((!_left && _msg->msgCtl()->rightRangeIdx() == 0) || (_left && _msg->msgCtl()->leftRangeIdx() == 0)) {
qreal vmin = std::numeric_limits<qreal>::max(); qreal vmin = std::numeric_limits<qreal>::max();
qreal vmax = std::numeric_limits<qreal>::min(); qreal vmax = std::numeric_limits<qreal>::min();
for(int i = 0; i < _values.count(); i++) { for(int i = 0; i < _values.count(); i++) {
qreal v = _values[i]; qreal v = _values[i].y();
if(vmax < v) vmax = v; if(vmax < v) vmax = v;
if(vmin > v) vmin = v; if(vmin > v) vmin = v;
} }
bool changed = false;
if(std::abs(_rangeMin - vmin) > 0.000001) { if(std::abs(_rangeMin - vmin) > 0.000001) {
_rangeMin = vmin; _rangeMin = vmin;
emit rangeMinChanged(); changed = true;
} }
if(std::abs(_rangeMax - vmax) > 0.000001) { if(std::abs(_rangeMax - vmax) > 0.000001) {
_rangeMax = vmax; _rangeMax = vmax;
emit rangeMaxChanged(); changed = true;
}
if(changed) {
_msg->msgCtl()->updateYRange(_left);
} }
} }
_msg->msgCtl()->updateXRange(); _msg->msgCtl()->updateXRange();
...@@ -166,14 +129,8 @@ QGCMAVLinkMessageField::_updateSeries() ...@@ -166,14 +129,8 @@ QGCMAVLinkMessageField::_updateSeries()
{ {
int count = _values.count(); int count = _values.count();
if (count > 1) { if (count > 1) {
_series.clear(); QLineSeries* lineSeries = static_cast<QLineSeries*>(_pSeries);
int idx = _dataIndex; lineSeries->replace(_values);
for(int i = 0; i < count; i++, idx++) {
if(idx >= count) idx = 0;
QPointF p(_times[idx], _values[idx]);
_series.append(p);
}
emit seriesChanged();
} }
} }
...@@ -539,6 +496,14 @@ MAVLinkInspectorController::TimeScale_st::TimeScale_st(QObject* parent, const QS ...@@ -539,6 +496,14 @@ MAVLinkInspectorController::TimeScale_st::TimeScale_st(QObject* parent, const QS
{ {
} }
//-----------------------------------------------------------------------------
MAVLinkInspectorController::Range_st::Range_st(QObject* parent, const QString& l, qreal r)
: QObject(parent)
, label(l)
, range(r)
{
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
MAVLinkInspectorController::MAVLinkInspectorController() MAVLinkInspectorController::MAVLinkInspectorController()
{ {
...@@ -551,22 +516,30 @@ MAVLinkInspectorController::MAVLinkInspectorController() ...@@ -551,22 +516,30 @@ MAVLinkInspectorController::MAVLinkInspectorController()
_updateTimer.start(1000); _updateTimer.start(1000);
MultiVehicleManager *manager = qgcApp()->toolbox()->multiVehicleManager(); MultiVehicleManager *manager = qgcApp()->toolbox()->multiVehicleManager();
connect(manager, &MultiVehicleManager::activeVehicleChanged, this, &MAVLinkInspectorController::_setActiveVehicle); connect(manager, &MultiVehicleManager::activeVehicleChanged, this, &MAVLinkInspectorController::_setActiveVehicle);
_rangeXMax = QDateTime::fromMSecsSinceEpoch(0);
_rangeXMin = QDateTime::fromMSecsSinceEpoch(std::numeric_limits<qint64>::max());
_timeScaleSt.append(new TimeScale_st(this, tr("5 Sec"), 5 * 1000)); _timeScaleSt.append(new TimeScale_st(this, tr("5 Sec"), 5 * 1000));
_timeScaleSt.append(new TimeScale_st(this, tr("10 Sec"), 10 * 1000)); _timeScaleSt.append(new TimeScale_st(this, tr("10 Sec"), 10 * 1000));
_timeScaleSt.append(new TimeScale_st(this, tr("30 Sec"), 30 * 1000)); _timeScaleSt.append(new TimeScale_st(this, tr("30 Sec"), 30 * 1000));
_timeScaleSt.append(new TimeScale_st(this, tr("60 Sec"), 60 * 1000)); _timeScaleSt.append(new TimeScale_st(this, tr("60 Sec"), 60 * 1000));
emit timeScalesChanged(); emit timeScalesChanged();
_rangeSt.append(new Range_st(this, tr("Auto"), 0));
_rangeSt.append(new Range_st(this, tr("10,000"), 10000));
_rangeSt.append(new Range_st(this, tr("1,000"), 1000));
_rangeSt.append(new Range_st(this, tr("100"), 100));
_rangeSt.append(new Range_st(this, tr("10"), 10));
_rangeSt.append(new Range_st(this, tr("1"), 1));
_rangeSt.append(new Range_st(this, tr("0.1"), 0.1));
_rangeSt.append(new Range_st(this, tr("0.01"), 0.01));
_rangeSt.append(new Range_st(this, tr("0.001"), 0.001));
_rangeSt.append(new Range_st(this, tr("0.0001"), 0.0001));
emit rangeListChanged();
updateXRange();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
MAVLinkInspectorController::~MAVLinkInspectorController() MAVLinkInspectorController::~MAVLinkInspectorController()
{ {
_reset();
} }
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
QStringList QStringList
MAVLinkInspectorController::timeScales() MAVLinkInspectorController::timeScales()
...@@ -579,6 +552,54 @@ MAVLinkInspectorController::timeScales() ...@@ -579,6 +552,54 @@ MAVLinkInspectorController::timeScales()
return _timeScales; return _timeScales;
} }
//----------------------------------------------------------------------------------------
QStringList
MAVLinkInspectorController::rangeList()
{
if(!_rangeList.count()) {
for(int i = 0; i < _rangeSt.count(); i++) {
_rangeList << _rangeSt[i]->label;
}
}
return _rangeList;
}
//-----------------------------------------------------------------------------
void
MAVLinkInspectorController::setLeftRangeIdx(quint32 r)
{
if(r < static_cast<quint32>(_rangeSt.count())) {
_leftRangeIndex = r;
_timeRange = _rangeSt[static_cast<int>(r)]->range;
emit leftRangeChanged();
//-- If not Auto, use defined range
if(_leftRangeIndex > 0) {
_leftRangeMin = -_timeRange;
emit leftRangeMinChanged();
_leftRangeMax = _timeRange;
emit leftRangeMaxChanged();
}
}
}
//-----------------------------------------------------------------------------
void
MAVLinkInspectorController::setRightRangeIdx(quint32 r)
{
if(r < static_cast<quint32>(_rangeSt.count())) {
_rightRangeIndex = r;
_timeRange = _rangeSt[static_cast<int>(r)]->range;
emit rightRangeChanged();
//-- If not Auto, use defined range
if(_rightRangeIndex > 0) {
_rightRangeMin = -_timeRange;
emit rightRangeMinChanged();
_rightRangeMax = _timeRange;
emit rightRangeMaxChanged();
}
}
}
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
void void
MAVLinkInspectorController::_setActiveVehicle(Vehicle* vehicle) MAVLinkInspectorController::_setActiveVehicle(Vehicle* vehicle)
...@@ -686,50 +707,51 @@ MAVLinkInspectorController::_receiveMessage(LinkInterface*, mavlink_message_t me ...@@ -686,50 +707,51 @@ MAVLinkInspectorController::_receiveMessage(LinkInterface*, mavlink_message_t me
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
MAVLinkInspectorController::_reset() MAVLinkInspectorController::addChartField(QGCMAVLinkMessageField* field, bool left)
{
}
//-----------------------------------------------------------------------------
void
MAVLinkInspectorController::addChartField(QGCMAVLinkMessageField* field)
{ {
QVariant f = QVariant::fromValue(field); QVariant f = QVariant::fromValue(field);
for(int i = 0; i < _chartFields.count(); i++) { QVariantList* pList;
if(_chartFields.at(i) == f) { if(left) {
pList = &_leftChartFields;
} else {
pList = &_rightChartFields;
}
for(int i = 0; i < pList->count(); i++) {
if(pList->at(i) == f) {
return; return;
} }
} }
_chartFields.append(f); pList->append(f);
emit chartFieldCountChanged(); if(left) {
emit leftChartFieldsChanged();
} else {
emit rightChartFieldsChanged();
}
emit seriesCountChanged();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
MAVLinkInspectorController::delChartField(QGCMAVLinkMessageField* field) MAVLinkInspectorController::delChartField(QGCMAVLinkMessageField* field, bool left)
{ {
QVariant f = QVariant::fromValue(field); QVariant f = QVariant::fromValue(field);
for(int i = 0; i < _chartFields.count(); i++) { QVariantList* pList;
if(_chartFields.at(i) == f) { if(left) {
_chartFields.removeAt(i); pList = &_leftChartFields;
emit chartFieldCountChanged(); } else {
if(_chartFields.count() == 0) { pList = &_rightChartFields;
_rangeXMax = QDateTime::fromMSecsSinceEpoch(0);
_rangeXMin = QDateTime::fromMSecsSinceEpoch(std::numeric_limits<qint64>::max());
} }
return; for(int i = 0; i < pList->count(); i++) {
if(pList->at(i) == f) {
pList->removeAt(i);
if(left) {
emit leftChartFieldsChanged();
} else {
emit rightChartFieldsChanged();
} }
emit seriesCountChanged();
return;
} }
}
//-----------------------------------------------------------------------------
void
MAVLinkInspectorController::updateSeries(int index, QAbstractSeries* series)
{
if(index < _chartFields.count() && series) {
QGCMAVLinkMessageField* f = qvariant_cast<QGCMAVLinkMessageField*>(_chartFields.at(index));
QLineSeries* lineSeries = static_cast<QLineSeries*>(series);
lineSeries->replace(f->series());
} }
} }
...@@ -754,3 +776,79 @@ MAVLinkInspectorController::updateXRange() ...@@ -754,3 +776,79 @@ MAVLinkInspectorController::updateXRange()
emit rangeMaxXChanged(); emit rangeMaxXChanged();
} }
} }
//-----------------------------------------------------------------------------
void
MAVLinkInspectorController::updateYRange(bool left)
{
QVariantList* pList;
if(left) {
pList = &_leftChartFields;
} else {
pList = &_rightChartFields;
}
if(pList->count()) {
qreal vmin = std::numeric_limits<qreal>::max();
qreal vmax = std::numeric_limits<qreal>::min();
for(int i = 0; i < pList->count(); i++) {
QObject* object = qvariant_cast<QObject*>(pList->at(i));
QGCMAVLinkMessageField* pField = qobject_cast<QGCMAVLinkMessageField*>(object);
if(pField) {
if(vmax < pField->rangeMax()) vmax = pField->rangeMax();
if(vmin > pField->rangeMin()) vmin = pField->rangeMin();
}
}
if(left) {
if(std::abs(_leftRangeMin - vmin) > 0.000001) {
_leftRangeMin = vmin;
emit leftRangeMinChanged();
}
if(std::abs(_leftRangeMax - vmax) > 0.000001) {
_leftRangeMax = vmax;
emit leftRangeMaxChanged();
}
} else {
if(std::abs(_rightRangeMin - vmin) > 0.000001) {
_rightRangeMin = vmin;
emit rightRangeMinChanged();
}
if(std::abs(_rightRangeMax - vmax) > 0.000001) {
_rightRangeMax = vmax;
emit rightRangeMaxChanged();
}
}
}
}
//-----------------------------------------------------------------------------
void
MAVLinkInspectorController::addSeries(QGCMAVLinkMessageField* field, QAbstractSeries* series, bool left)
{
if(field) {
field->addSeries(series, left);
}
}
//-----------------------------------------------------------------------------
void
MAVLinkInspectorController::delSeries(QGCMAVLinkMessageField* field)
{
if(field) {
field->delSeries();
}
if(_leftChartFields.count() == 0) {
_leftRangeMin = 0;
_leftRangeMax = 1;
emit leftRangeMinChanged();
emit leftRangeMaxChanged();
}
if(_rightChartFields.count() == 0) {
_rightRangeMin = 0;
_rightRangeMax = 1;
emit rightRangeMinChanged();
emit rightRangeMaxChanged();
}
if(_leftChartFields.count() == 0 && _rightChartFields.count() == 0) {
updateXRange();
}
}
...@@ -32,12 +32,9 @@ class QGCMAVLinkMessageField : public QObject { ...@@ -32,12 +32,9 @@ class QGCMAVLinkMessageField : public QObject {
Q_PROPERTY(QString label READ label CONSTANT) Q_PROPERTY(QString label READ label CONSTANT)
Q_PROPERTY(QString type READ type CONSTANT) Q_PROPERTY(QString type READ type CONSTANT)
Q_PROPERTY(QString value READ value NOTIFY valueChanged) Q_PROPERTY(QString value READ value NOTIFY valueChanged)
Q_PROPERTY(QStringList rangeList READ rangeList NOTIFY rangeListChanged)
Q_PROPERTY(qreal rangeMin READ rangeMin NOTIFY rangeMinChanged)
Q_PROPERTY(qreal rangeMax READ rangeMax NOTIFY rangeMaxChanged)
Q_PROPERTY(bool selectable READ selectable NOTIFY selectableChanged) Q_PROPERTY(bool selectable READ selectable NOTIFY selectableChanged)
Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectedChanged) Q_PROPERTY(bool left READ left NOTIFY seriesChanged)
Q_PROPERTY(quint32 range READ range WRITE setRange NOTIFY rangeChanged) Q_PROPERTY(QAbstractSeries* series READ series NOTIFY seriesChanged)
public: public:
QGCMAVLinkMessageField(QGCMAVLinkMessage* parent, QString name, QString type); QGCMAVLinkMessageField(QGCMAVLinkMessage* parent, QString name, QString type);
...@@ -46,57 +43,42 @@ public: ...@@ -46,57 +43,42 @@ public:
QString label (); QString label ();
QString type () { return _type; } QString type () { return _type; }
QString value () { return _value; } QString value () { return _value; }
QStringList rangeList (); bool selectable () { return _selectable; }
bool selected () { return _pSeries != nullptr; }
bool left () { return _left; }
QAbstractSeries*series () { return _pSeries; }
QList<QPointF>* values () { return &_values;}
qreal rangeMin () { return _rangeMin; } qreal rangeMin () { return _rangeMin; }
qreal rangeMax () { return _rangeMax; } qreal rangeMax () { return _rangeMax; }
QList<QPointF> series () { return _series; }
bool selectable () { return _selectable; }
bool selected () { return _selected; }
quint32 range () { return _rangeIndex; }
void setSelectable (bool sel); void setSelectable (bool sel);
void setSelected (bool sel);
void setRange (quint32 r);
void updateValue (QString newValue, qreal v); void updateValue (QString newValue, qreal v);
void addSeries (QAbstractSeries* series, bool left);
void delSeries ();
signals: signals:
void rangeMinChanged ();
void rangeMaxChanged ();
void seriesChanged (); void seriesChanged ();
void selectableChanged (); void selectableChanged ();
void selectedChanged ();
void valueChanged (); void valueChanged ();
void rangeListChanged ();
void rangeChanged ();
private: private:
void _updateSeries (); void _updateSeries ();
private: private:
class Range_st : public QObject {
public:
Range_st(QObject* parent, const QString& l, qreal r);
QString label;
qreal range;
};
QString _type; QString _type;
QString _name; QString _name;
QString _value; QString _value;
QGCMAVLinkMessage* _msg = nullptr;
bool _selectable = true; bool _selectable = true;
bool _selected = false; bool _left = false;
int _dataIndex = 0; int _dataIndex = 0;
qreal _rangeMin = 0; qreal _rangeMin = 0;
qreal _rangeMax = 0; qreal _rangeMax = 0;
quint32 _rangeIndex = 0; ///> Auto Range
qreal _range = 0; QAbstractSeries* _pSeries = nullptr;
QStringList _rangeList; QGCMAVLinkMessage* _msg = nullptr;
QVector<qreal> _values; QList<QPointF> _values;
QVector<quint64> _times;
QList<QPointF> _series;
QList<Range_st*> _rangeSt;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -189,38 +171,70 @@ public: ...@@ -189,38 +171,70 @@ public:
Q_PROPERTY(QStringList vehicleNames READ vehicleNames NOTIFY vehiclesChanged) Q_PROPERTY(QStringList vehicleNames READ vehicleNames NOTIFY vehiclesChanged)
Q_PROPERTY(QmlObjectListModel* vehicles READ vehicles NOTIFY vehiclesChanged) Q_PROPERTY(QmlObjectListModel* vehicles READ vehicles NOTIFY vehiclesChanged)
Q_PROPERTY(QGCMAVLinkVehicle* activeVehicle READ activeVehicle NOTIFY activeVehiclesChanged) Q_PROPERTY(QGCMAVLinkVehicle* activeVehicle READ activeVehicle NOTIFY activeVehiclesChanged)
Q_PROPERTY(int chartFieldCount READ chartFieldCount NOTIFY chartFieldCountChanged) Q_PROPERTY(QVariantList rightChartFields READ rightChartFields NOTIFY rightChartFieldsChanged)
Q_PROPERTY(QVariantList chartFields READ chartFields NOTIFY chartFieldCountChanged) Q_PROPERTY(QVariantList leftChartFields READ leftChartFields NOTIFY leftChartFieldsChanged)
Q_PROPERTY(int seriesCount READ seriesCount NOTIFY seriesCountChanged)
Q_PROPERTY(QDateTime rangeXMin READ rangeXMin NOTIFY rangeMinXChanged) Q_PROPERTY(QDateTime rangeXMin READ rangeXMin NOTIFY rangeMinXChanged)
Q_PROPERTY(QDateTime rangeXMax READ rangeXMax NOTIFY rangeMaxXChanged) Q_PROPERTY(QDateTime rangeXMax READ rangeXMax NOTIFY rangeMaxXChanged)
Q_PROPERTY(qreal rightRangeMin READ rightRangeMin NOTIFY rightRangeMinChanged)
Q_PROPERTY(qreal rightRangeMax READ rightRangeMax NOTIFY rightRangeMaxChanged)
Q_PROPERTY(qreal leftRangeMin READ leftRangeMin NOTIFY leftRangeMinChanged)
Q_PROPERTY(qreal leftRangeMax READ leftRangeMax NOTIFY leftRangeMaxChanged)
Q_PROPERTY(QStringList timeScales READ timeScales NOTIFY timeScalesChanged) Q_PROPERTY(QStringList timeScales READ timeScales NOTIFY timeScalesChanged)
Q_PROPERTY(QStringList rangeList READ rangeList NOTIFY rangeListChanged)
Q_PROPERTY(quint32 leftRangeIdx READ leftRangeIdx WRITE setLeftRangeIdx NOTIFY leftRangeChanged)
Q_PROPERTY(quint32 rightRangeIdx READ rightRangeIdx WRITE setRightRangeIdx NOTIFY rightRangeChanged)
Q_PROPERTY(quint32 timeScale READ timeScale WRITE setTimeScale NOTIFY timeScaleChanged) Q_PROPERTY(quint32 timeScale READ timeScale WRITE setTimeScale NOTIFY timeScaleChanged)
Q_INVOKABLE void updateSeries (int index, QAbstractSeries *series); Q_INVOKABLE void addSeries (QGCMAVLinkMessageField* field, QAbstractSeries* series, bool left);
Q_INVOKABLE void delSeries (QGCMAVLinkMessageField* field);
QmlObjectListModel* vehicles () { return &_vehicles; } QmlObjectListModel* vehicles () { return &_vehicles; }
QGCMAVLinkVehicle* activeVehicle () { return _activeVehicle; } QGCMAVLinkVehicle* activeVehicle () { return _activeVehicle; }
QStringList vehicleNames () { return _vehicleNames; } QStringList vehicleNames () { return _vehicleNames; }
quint32 timeScale () { return _timeScale; } quint32 timeScale () { return _timeScale; }
QStringList timeScales (); QStringList timeScales ();
QVariantList chartFields () { return _chartFields; } int seriesCount () { return _rightChartFields.count() + _leftChartFields.count(); }
QStringList rangeList ();
QVariantList rightChartFields () { return _rightChartFields; }
QVariantList leftChartFields () { return _leftChartFields; }
QDateTime rangeXMin () { return _rangeXMin; } QDateTime rangeXMin () { return _rangeXMin; }
QDateTime rangeXMax () { return _rangeXMax; } QDateTime rangeXMax () { return _rangeXMax; }
qreal rightRangeMin () { return _rightRangeMin; }
qreal rightRangeMax () { return _rightRangeMax; }
quint32 rightRangeIdx () { return _rightRangeIndex; }
qreal leftRangeMin () { return _leftRangeMin; }
qreal leftRangeMax () { return _leftRangeMax; }
quint32 leftRangeIdx () { return _leftRangeIndex; }
void setTimeScale (quint32 t); void setTimeScale (quint32 t);
int chartFieldCount () { return _chartFields.count(); } void setRightRangeIdx (quint32 r);
void addChartField (QGCMAVLinkMessageField* field); void setLeftRangeIdx (quint32 r);
void delChartField (QGCMAVLinkMessageField* field); void addChartField (QGCMAVLinkMessageField* field, bool left);
void delChartField (QGCMAVLinkMessageField* field, bool left);
void updateXRange (); void updateXRange ();
void updateYRange (bool left);
signals: signals:
void vehiclesChanged (); void vehiclesChanged ();
void activeVehiclesChanged (); void activeVehiclesChanged ();
void chartFieldCountChanged (); void rightChartFieldsChanged ();
void leftChartFieldsChanged ();
void timeScaleChanged (); void timeScaleChanged ();
void rangeMinXChanged (); void rangeMinXChanged ();
void rangeMaxXChanged (); void rangeMaxXChanged ();
void timeScalesChanged (); void timeScalesChanged ();
void rangeListChanged ();
void rightRangeMinChanged ();
void rightRangeMaxChanged ();
void rightRangeChanged ();
void leftRangeMinChanged ();
void leftRangeMaxChanged ();
void leftRangeChanged ();
void seriesCountChanged ();
private slots: private slots:
void _receiveMessage (LinkInterface* link, mavlink_message_t message); void _receiveMessage (LinkInterface* link, mavlink_message_t message);
...@@ -230,7 +244,6 @@ private slots: ...@@ -230,7 +244,6 @@ private slots:
void _refreshFrequency (); void _refreshFrequency ();
private: private:
void _reset ();
QGCMAVLinkVehicle* _findVehicle (uint8_t id); QGCMAVLinkVehicle* _findVehicle (uint8_t id);
private: private:
...@@ -242,16 +255,33 @@ private: ...@@ -242,16 +255,33 @@ private:
uint32_t timeScale; uint32_t timeScale;
}; };
class Range_st : public QObject {
public:
Range_st(QObject* parent, const QString& l, qreal r);
QString label;
qreal range;
};
int _selectedSystemID = 0; ///< Currently selected system int _selectedSystemID = 0; ///< Currently selected system
int _selectedComponentID = 0; ///< Currently selected component int _selectedComponentID = 0; ///< Currently selected component
QStringList _timeScales; QStringList _timeScales;
QStringList _rangeList;
quint32 _timeScale = 0; ///< 5 Seconds quint32 _timeScale = 0; ///< 5 Seconds
QDateTime _rangeXMin; QDateTime _rangeXMin;
QDateTime _rangeXMax; QDateTime _rangeXMax;
qreal _leftRangeMin = 0;
qreal _leftRangeMax = 1;
quint32 _leftRangeIndex = 0; ///> Auto Range
qreal _rightRangeMin = 0;
qreal _rightRangeMax = 1;
quint32 _rightRangeIndex = 0; ///> Auto Range
qreal _timeRange = 0;
QGCMAVLinkVehicle* _activeVehicle = nullptr; QGCMAVLinkVehicle* _activeVehicle = nullptr;
QTimer _updateTimer; QTimer _updateTimer;
QStringList _vehicleNames; QStringList _vehicleNames;
QmlObjectListModel _vehicles; ///< List of QGCMAVLinkVehicle QmlObjectListModel _vehicles; ///< List of QGCMAVLinkVehicle
QVariantList _chartFields; QVariantList _rightChartFields;
QVariantList _leftChartFields;
QList<TimeScale_st*>_timeScaleSt; QList<TimeScale_st*>_timeScaleSt;
QList<Range_st*> _rangeSt;
}; };
...@@ -257,14 +257,16 @@ AnalyzePage { ...@@ -257,14 +257,16 @@ AnalyzePage {
QGCLabel { QGCLabel {
text: qsTr("Message Fields:") text: qsTr("Message Fields:")
} }
//---------------------------------------------------------
Rectangle { Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
height: 1 height: 1
color: qgcPal.text color: qgcPal.text
} }
Item { height: ScreenTools.defaultFontPixelHeight * 0.25; width: 1 } Item { height: ScreenTools.defaultFontPixelHeight * 0.25; width: 1 }
//---------------------------------------------------------
GridLayout { GridLayout {
columns: 4 columns: 5
columnSpacing: ScreenTools.defaultFontPixelWidth columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25 rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25
Repeater { Repeater {
...@@ -299,9 +301,35 @@ AnalyzePage { ...@@ -299,9 +301,35 @@ AnalyzePage {
delegate: QGCCheckBox { delegate: QGCCheckBox {
Layout.row: index Layout.row: index
Layout.column: 3 Layout.column: 3
enabled: object.selected || (object.selectable && controller.chartFieldCount < 2) enabled: (object.series !== null && object.left) || (object.selectable && controller.seriesCount < chartView.maxSeriesCount)
checked: enabled ? object.selected : false checked: enabled ? (object.series !== null && object.left) : false
onClicked: { if(enabled) object.selected = checked } onClicked: {
if(enabled) {
if(checked) {
chartView.addDimension(object, true)
} else {
chartView.delDimension(object)
}
}
}
}
}
Repeater {
model: curMessage ? curMessage.fields : []
delegate: QGCCheckBox {
Layout.row: index
Layout.column: 4
enabled: (object.series !== null && !object.left) || (object.selectable && controller.seriesCount < chartView.maxSeriesCount && (object.series === null && !object.left))
checked: enabled ? (object.series !== null && !object.left) : false
onClicked: {
if(enabled) {
if(checked) {
chartView.addDimension(object, false)
} else {
chartView.delDimension(object)
}
}
}
} }
} }
} }
...@@ -312,86 +340,69 @@ AnalyzePage { ...@@ -312,86 +340,69 @@ AnalyzePage {
height: ScreenTools.defaultFontPixelHeight * 20 height: ScreenTools.defaultFontPixelHeight * 20
theme: ChartView.ChartThemeDark theme: ChartView.ChartThemeDark
antialiasing: true antialiasing: true
visible: controller.chartFieldCount > 0 visible: controller.leftChartFields.length > 0 || controller.rightChartFields.length > 0
animationOptions: ChartView.NoAnimation animationOptions: ChartView.NoAnimation
legend.visible: false legend.visible: false
margins.bottom: ScreenTools.defaultFontPixelHeight * 1.5 margins.bottom: ScreenTools.defaultFontPixelHeight * 1.5
margins.top: chartHeader.height + (ScreenTools.defaultFontPixelHeight * 2) margins.top: chartHeader.height + (ScreenTools.defaultFontPixelHeight * 2)
property int maxSeriesCount: seriesColors.length
property var seriesColors: ["antiquewhite", "aqua", "chartreuse", "chocolate", "crimson", "darkturquoise", "aquamarine", "azure", "coral", "cornflowerblue", "darkorange", "gold", "hotpink", "lavenderblush", "lightskyblue"]
function addDimension(field, left) {
console.log(field.name + ' ' + field + ' AxisY1: ' + axisY1 + ' AxisY2: ' + axisY2)
console.log(controller.seriesCount + ' ' + chartView.seriesColors[controller.seriesCount])
var serie = createSeries(ChartView.SeriesTypeLine, field.label)
serie.axisX = axisX
if(left) {
serie.axisY = axisY1
} else {
serie.axisYRight = axisY2
}
serie.useOpenGL = true
serie.color = chartView.seriesColors[controller.seriesCount]
controller.addSeries(field, serie, left)
}
function delDimension(field) {
chartView.removeSeries(field.series)
controller.delSeries(field)
console.log('Remove: ' + controller.seriesCount + ' ' + field.name)
}
DateTimeAxis { DateTimeAxis {
id: axisX id: axisX
min: visible ? controller.rangeXMin : new Date() min: visible ? controller.rangeXMin : new Date()
max: visible ? controller.rangeXMax : new Date() max: visible ? controller.rangeXMax : new Date()
visible: controller.chartFieldCount > 0 format: "hh:mm:ss"
format: "mm:ss"
tickCount: 5 tickCount: 5
gridVisible: true gridVisible: true
labelsFont.family: "Fixed"
labelsFont.pixelSize: ScreenTools.smallFontPointSize labelsFont.pixelSize: ScreenTools.smallFontPointSize
} }
ValueAxis { ValueAxis {
id: axisY1 id: axisY1
min: visible ? controller.chartFields[0].rangeMin : 0 min: visible ? controller.leftRangeMin : 0
max: visible ? controller.chartFields[0].rangeMax : 0 max: visible ? controller.leftRangeMax : 0
visible: controller.chartFieldCount > 0 visible: controller.leftChartFields.length > 0
lineVisible: false lineVisible: false
labelsFont.family: "Fixed"
labelsFont.pixelSize: ScreenTools.smallFontPointSize labelsFont.pixelSize: ScreenTools.smallFontPointSize
labelsColor: qgcPal.colorRed //labelsColor: qgcPal.colorRed
} }
ValueAxis { ValueAxis {
id: axisY2 id: axisY2
min: visible ? controller.chartFields[1].rangeMin : 0 min: visible ? controller.rightRangeMin : 0
max: visible ? controller.chartFields[1].rangeMax : 0 max: visible ? controller.rightRangeMax : 0
visible: controller.chartFieldCount > 1 visible: controller.rightChartFields.length > 0
lineVisible: false lineVisible: false
labelsFont.family: "Fixed"
labelsFont.pixelSize: ScreenTools.smallFontPointSize labelsFont.pixelSize: ScreenTools.smallFontPointSize
labelsColor: qgcPal.colorGreen //labelsColor: qgcPal.colorGreen
}
LineSeries {
id: lineSeries1
name: controller.chartFieldCount ? controller.chartFields[0].label : ""
axisX: axisX
axisY: axisY1
color: qgcPal.colorRed
useOpenGL: true
}
LineSeries {
id: lineSeries2
name: controller.chartFieldCount > 1 ? controller.chartFields[1].label : ""
axisX: axisX
axisYRight: axisY2
color: qgcPal.colorGreen
useOpenGL: true
} }
Timer {
id: refreshTimer
interval: 1 / 20 * 1000 // 20 Hz
running: controller.chartFieldCount > 0
repeat: true
onTriggered: {
if(controller.chartFieldCount > 0) {
controller.updateSeries(0, lineSeries1)
}
if(controller.chartFieldCount > 1) {
controller.updateSeries(1, lineSeries2)
} else {
if(lineSeries2.count > 0) {
lineSeries2.removePoints(0,lineSeries2.count)
}
}
}
onRunningChanged: {
if(!running) {
if(lineSeries1.count > 0) {
lineSeries1.removePoints(0,lineSeries1.count)
}
}
}
}
RowLayout { RowLayout {
id: chartHeader id: chartHeader
anchors.left: parent.left anchors.left: parent.left
...@@ -417,43 +428,37 @@ AnalyzePage { ...@@ -417,43 +428,37 @@ AnalyzePage {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
} }
GridLayout { GridLayout {
columns: 3 columns: 2
columnSpacing: ScreenTools.defaultFontPixelWidth columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25 rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Layout.fillWidth: true Layout.fillWidth: true
Repeater { QGCLabel {
model: controller.chartFieldCount ? controller.chartFields : [] text: qsTr("Range Left:");
delegate: QGCLabel {
text: chartView.series(index).name
color: chartView.series(index).color
font.pixelSize: ScreenTools.smallFontPointSize font.pixelSize: ScreenTools.smallFontPointSize
Layout.row: index
Layout.column: 0
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
} }
} QGCComboBox {
Repeater { Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 8
model: controller.chartFieldCount ? controller.chartFields : [] height: ScreenTools.defaultFontPixelHeight * 1.5
delegate: QGCLabel { model: controller.rangeList
text: qsTr("Range:"); currentIndex: controller.leftRangeIdx
onActivated: controller.leftRangeIdx = index
font.pixelSize: ScreenTools.smallFontPointSize font.pixelSize: ScreenTools.smallFontPointSize
Layout.row: index
Layout.column: 1
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
} }
QGCLabel {
text: qsTr("Range Right:");
font.pixelSize: ScreenTools.smallFontPointSize
Layout.alignment: Qt.AlignVCenter
} }
Repeater { QGCComboBox {
model: controller.chartFieldCount ? controller.chartFields : [] Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 8
delegate: QGCComboBox {
width: ScreenTools.defaultFontPixelWidth * 12
height: ScreenTools.defaultFontPixelHeight * 1.5 height: ScreenTools.defaultFontPixelHeight * 1.5
model: modelData.rangeList model: controller.rangeList
currentIndex: modelData.range currentIndex: controller.rightRangeIdx
onActivated: modelData.range = index onActivated: controller.rightRangeIdx = index
font.pixelSize: ScreenTools.smallFontPointSize font.pixelSize: ScreenTools.smallFontPointSize
Layout.row: index
Layout.column: 2
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
} }
} }
...@@ -463,5 +468,4 @@ AnalyzePage { ...@@ -463,5 +468,4 @@ AnalyzePage {
} }
} }
} }
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment