Add plot divisions control

This commit is contained in:
Alex Spataru 2021-10-06 14:44:34 -05:00
parent 7ab9f8efe0
commit 5ec91e6d87
7 changed files with 140 additions and 11 deletions

1
assets/icons/points.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10 12c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zM6 8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12-8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm-4 8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm4-4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-4-4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-4-4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></svg>

After

Width:  |  Height:  |  Size: 549 B

View File

@ -72,5 +72,6 @@
<file>show-all.svg</file>
<file>hide-all.svg</file>
<file>multiplot.svg</file>
<file>points.svg</file>
</qresource>
</RCC>

View File

@ -23,6 +23,7 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Qt.labs.settings 1.0
import "../Widgets" as Widgets
@ -38,6 +39,40 @@ Widgets.Window {
icon.source: "qrc:/icons/visibility.svg"
backgroundColor: Cpp_ThemeManager.embeddedWindowBackground
//
// Maps the slider position to points
// https://stackoverflow.com/a/846249
//
function logslider(position) {
var minp = 0
var maxp = 100
var minv = Math.log(10)
var maxv = Math.log(10000)
var scale = (maxv - minv) / (maxp - minp);
return Math.exp(minv + scale * (position - minp)).toFixed(0);
}
//
// Maps the points value to the slider position
// https://stackoverflow.com/a/846249
//
function logposition(value) {
var minp = 0
var maxp = 100
var minv = Math.log(10)
var maxv = Math.log(10000)
var scale = (maxv - minv) / (maxp - minp)
var result = (Math.log(value) - minv) / scale + minp;
return result.toFixed(0)
}
//
// Settings
//
Settings {
property alias points: dial.value
}
//
// Put all items inside a scrollview
//
@ -53,6 +88,7 @@ Widgets.Window {
// Main layout
//
ColumnLayout {
id: layout
x: app.spacing
spacing: app.spacing / 2
width: parent.width - 10 - 2 * app.spacing
@ -64,6 +100,57 @@ Widgets.Window {
height: app.spacing
}
//
// Horizontal range title
//
RowLayout {
spacing: app.spacing
Layout.fillWidth: true
visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0
Widgets.Icon {
width: 18
height: 18
color: palette.text
source: "qrc:/icons/points.svg"
}
Label {
font.bold: true
text: qsTr("Plot divisions (%1)").arg(logslider(dial.value))
}
Item {
Layout.fillWidth: true
}
}
//
// Horizontal scale controls
//
Dial {
id: dial
to: 100
from: 10
value: logposition(100)
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
visible: Cpp_UI_Dashboard.plotCount > 0 || Cpp_UI_Dashboard.multiPlotCount > 0
onValueChanged: {
var log = logslider(value)
if (Cpp_UI_Dashboard.points !== log)
Cpp_UI_Dashboard.points = log
}
}
//
// Spacer
//
Item {
height: app.spacing
}
//
// Groups
//

View File

@ -43,7 +43,8 @@ static Dashboard *INSTANCE = nullptr;
* Constructor of the class.
*/
Dashboard::Dashboard()
: m_latestJsonFrame(JFI_Empty())
: m_points(100),
m_latestJsonFrame(JFI_Empty())
{
auto cp = CSV::Player::getInstance();
auto io = IO::Manager::getInstance();
@ -108,6 +109,13 @@ bool Dashboard::available()
return totalWidgetCount() > 0;
}
/**
* Returns the number of points displayed by the graphs
*/
int Dashboard::points() const {
return m_points;
}
/**
* Returns @c true if the current JSON frame is valid and ready-to-use by the QML
* interface.
@ -494,6 +502,17 @@ QVector<QString> Dashboard::multiPlotTitles() const { return groupTitles(m_m
QVector<QString> Dashboard::accelerometerTitles() const { return groupTitles(m_accelerometerWidgets); }
// clang-format on
//--------------------------------------------------------------------------------------------------
// Plot options
//--------------------------------------------------------------------------------------------------
void Dashboard::setPoints(const int points) {
if (m_points != points) {
m_points = points;
emit pointsChanged();
}
}
//--------------------------------------------------------------------------------------------------
// Visibility-related slots
//--------------------------------------------------------------------------------------------------

View File

@ -40,6 +40,10 @@ class Dashboard : public QObject
Q_PROPERTY(bool available
READ available
NOTIFY widgetCountChanged)
Q_PROPERTY(int points
READ points
WRITE setPoints
NOTIFY pointsChanged)
Q_PROPERTY(int totalWidgetCount
READ totalWidgetCount
NOTIFY widgetCountChanged)
@ -103,6 +107,7 @@ signals:
void updated();
void dataReset();
void titleChanged();
void pointsChanged();
void widgetCountChanged();
void widgetVisibilityChanged();
@ -137,6 +142,7 @@ public:
QString title();
bool available();
int points() const;
int totalWidgetCount() const;
int mapCount() const;
@ -177,6 +183,7 @@ public:
QVector<QString> accelerometerTitles() const;
public slots:
void setPoints(const int points);
void setBarVisible(const int index, const bool visible);
void setMapVisible(const int index, const bool visible);
void setPlotVisible(const int index, const bool visible);
@ -210,6 +217,8 @@ private:
const int index);
private:
int m_points;
QVector<bool> m_barVisibility;
QVector<bool> m_mapVisibility;
QVector<bool> m_plotVisibility;

View File

@ -61,17 +61,8 @@ Plot::Plot(const int index)
m_layout.setContentsMargins(24, 24, 24, 24);
setLayout(&m_layout);
// Add 100 points to the plot
m_xData.reserve(100);
m_yData.reserve(100);
for (int i = 0; i < 100; ++i)
{
m_xData.append(i);
m_yData.append(0);
}
// Create curve from data
m_curve.setSamples(m_xData, m_yData);
updateRange();
m_curve.attach(&m_plot);
m_plot.replot();
m_plot.show();
@ -108,6 +99,7 @@ Plot::Plot(const int index)
// React to dashboard events
connect(dash, SIGNAL(updated()), this, SLOT(updateData()));
connect(dash, SIGNAL(pointsChanged()), this, SLOT(updateRange()));
}
void Plot::updateData()
@ -141,3 +133,22 @@ void Plot::updateData()
m_plot.replot();
}
}
void Plot::updateRange() {
// Get pointer to dashboard manager
auto dash = UI::Dashboard::getInstance();
// Set number of points
m_xData.clear();
m_yData.clear();
m_xData.reserve(dash->points());
m_yData.reserve(dash->points());
for (int i = 0; i < dash->points(); ++i)
{
m_xData.append(i);
m_yData.append(0);
}
// Create curve from data
m_curve.setSamples(m_xData, m_yData);
}

View File

@ -40,6 +40,7 @@ public:
private slots:
void updateData();
void updateRange();
private:
int m_index;