From aa680622c0364df36a20ddbbd801102a6b5003b9 Mon Sep 17 00:00:00 2001 From: mgrojo Date: Sat, 20 Jan 2018 18:08:31 +0100 Subject: [PATCH 1/4] Bar charts and Axis Type column in Plot Dock String type columns are now selectable as X axis. In that case a bar chart is plotted where the column values are used as bar labels. A new Axis Type column is added to the axis selection table, so the user knows before-hand how the plot will be drawn. Line type and point shape combo-boxes are not enabled for bar charts, since they don't make sense. Columns that make no sense for the Y axis as strings and date/times are not selectable for that axis. --- src/PlotDock.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++---- src/PlotDock.h | 1 + src/PlotDock.ui | 7 +++++- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/PlotDock.cpp b/src/PlotDock.cpp index d1e2daf2..5cd3c9ec 100644 --- a/src/PlotDock.cpp +++ b/src/PlotDock.cpp @@ -119,9 +119,27 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett for(int i=0;icolumnCount();++i) { QVariant::Type columntype = guessDataType(model, i); - if(columntype != QVariant::String && columntype != QVariant::Invalid) + if(columntype != QVariant::Invalid) { QTreeWidgetItem* columnitem = new QTreeWidgetItem(ui->treePlotColumns); + + switch (columntype) { + case QVariant::DateTime: + columnitem->setText(PlotColumnType, "Date/Time"); + break; + case QVariant::Date: + columnitem->setText(PlotColumnType, "Date"); + break; + case QVariant::Time: + columnitem->setText(PlotColumnType, "Time"); + break; + case QVariant::Double: + columnitem->setText(PlotColumnType, "Numeric"); + break; + case QVariant::String: + columnitem->setText(PlotColumnType, "Label"); + break; + } // maybe i make this more complicated than i should // but store the model column index in the first 16 bit and the type // in the other 16 bits @@ -137,7 +155,8 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett columnitem->setCheckState(PlotColumnY, mapItemsY[columnitem->text(PlotColumnField)].active ? Qt::Checked : Qt::Unchecked); columnitem->setBackgroundColor(PlotColumnY, mapItemsY[columnitem->text(PlotColumnField)].colour); } else { - columnitem->setCheckState(PlotColumnY, Qt::Unchecked); + if (columntype == QVariant::Double) + columnitem->setCheckState(PlotColumnY, Qt::Unchecked); } if(sItemX == columnitem->text(PlotColumnField)) @@ -146,6 +165,7 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett columnitem->setCheckState(PlotColumnX, Qt::Unchecked); } } + ui->treePlotColumns->resizeColumnToContents(PlotColumnField); // Add a row number column at the beginning of the column list, but only when there were (other) columns added @@ -157,6 +177,7 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett uint itemdata = -1; columnitem->setData(PlotColumnField, Qt::UserRole, itemdata); columnitem->setText(PlotColumnField, tr("Row #")); + columnitem->setText(PlotColumnType, "Numeric"); // restore previous check state if(mapItemsY.contains(columnitem->text(PlotColumnField))) @@ -229,6 +250,9 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett ui->plotWidget->xAxis->setTicker(ticker); break; } + case QVariant::String: { + break; + } default: { QSharedPointer ticker(new QCPAxisTickerFixed); ticker->setTickStepStrategy(QCPAxisTicker::tssReadability); @@ -254,6 +278,7 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett // possible improvement might be a QVector subclass that directly // access the model data, to save memory, we are copying here QVector xdata(model->rowCount()), ydata(model->rowCount()), tdata(model->rowCount()); + QVector labels; for(int i = 0; i < model->rowCount(); ++i) { tdata[i] = i; @@ -272,6 +297,11 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett xdata[i] = t.msecsSinceStartOfDay() / 1000.0; break; } + case QVariant::String: { + xdata[i] = i+1; + labels << model->data(model->index(i, x)).toString(); + break; + } default: { // Get the x value for this point. If the selected column is -1, i.e. the row number, just use the current row number from the loop // instead of retrieving some value from the model. @@ -299,6 +329,11 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett else ydata[i] = pointdata.toDouble(); } + + // Line type and point shape are not supported by the String X type (Bars) + ui->comboLineType->setEnabled(xtype != QVariant::String); + ui->comboPointShape->setEnabled(xtype != QVariant::String); + // WARN: ssDot is removed int shapeIdx = ui->comboPointShape->currentIndex(); if (shapeIdx > 0) shapeIdx += 1; @@ -309,13 +344,23 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett // When it is not sorted by x, we draw a curve, so the order selected by the user in the table or in the query is // respected. In this case the line will have loops and only None and Line is supported as line style. // TODO: how to make the user aware of this without disturbing. - if (isSorted) { + if (xtype == QVariant::String) { + QCPBars* bars = new QCPBars(ui->plotWidget->xAxis, ui->plotWidget->yAxis); + plottable = bars; + bars->setData(xdata, ydata); + bars->setBrush(item->backgroundColor(PlotColumnY)); + QSharedPointer ticker(new QCPAxisTickerText); + ticker->addTicks(xdata, labels); + ui->plotWidget->xAxis->setTicker(ticker); + ui->plotWidget->xAxis->setTickLabelRotation(60); + } else if (isSorted) { QCPGraph* graph = ui->plotWidget->addGraph(); plottable = graph; graph->setData(xdata, ydata, /*alreadySorted*/ true); // set some graph styles not supported by the abstract plottable graph->setLineStyle((QCPGraph::LineStyle) ui->comboLineType->currentIndex()); graph->setScatterStyle(scatterStyle); + ui->plotWidget->xAxis->setTickLabelRotation(0); } else { QCPCurve* curve = new QCPCurve(ui->plotWidget->xAxis, ui->plotWidget->yAxis); @@ -327,6 +372,7 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett else curve->setLineStyle(QCPCurve::lsLine); curve->setScatterStyle(scatterStyle); + ui->plotWidget->xAxis->setTickLabelRotation(0); } plottable->setPen(QPen(item->backgroundColor(PlotColumnY))); @@ -483,7 +529,10 @@ void PlotDock::on_treePlotColumns_itemDoubleClicked(QTreeWidgetItem* item, int c // disable change updates, or we get unwanted redrawing and weird behavior ui->treePlotColumns->blockSignals(true); - if(column == PlotColumnY) + uint itemdata = item->data(PlotColumnField, Qt::UserRole).toUInt(); + int type = itemdata & (uint)0xFF; + + if(column == PlotColumnY && type == QVariant::Double) { // On double click open the colordialog QColorDialog colordialog(this); diff --git a/src/PlotDock.h b/src/PlotDock.h index 5b296012..6acc02dd 100644 --- a/src/PlotDock.h +++ b/src/PlotDock.h @@ -77,6 +77,7 @@ private: PlotColumnField = 0, PlotColumnX = 1, PlotColumnY = 2, + PlotColumnType = 3, }; Ui::PlotDock* ui; diff --git a/src/PlotDock.ui b/src/PlotDock.ui index b001546c..b9a7e553 100644 --- a/src/PlotDock.ui +++ b/src/PlotDock.ui @@ -30,7 +30,7 @@ true - 3 + 4 100 @@ -53,6 +53,11 @@ Y + + + Axis Type + + From 175407645be3e5acf30a4e5b95fc33410ef1de42 Mon Sep 17 00:00:00 2001 From: mgrojo Date: Sat, 20 Jan 2018 18:28:03 +0100 Subject: [PATCH 2/4] Simplify the axis type storing, translucent additional bars and What's This Now that we have a proper type column in the plot selection widget, the internal type storing can be simplified. If the plot has more than one Y selections for one X of label type (bar charts) the first bar is opaque, but the additional are translucent in order to be seen, since they will overlap. What's This information added to explain all the possible selections for plotting. --- src/PlotDock.cpp | 46 +++++++++++++++++++++------------------------- src/PlotDock.ui | 3 +++ 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/PlotDock.cpp b/src/PlotDock.cpp index 5cd3c9ec..7e37c1cc 100644 --- a/src/PlotDock.cpp +++ b/src/PlotDock.cpp @@ -72,8 +72,8 @@ PlotDock::~PlotDock() void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* settings, bool update, bool keepOrResetSelection) { // Each column has an id that we use internally, starting from 0. However, at the beginning of the columns list we want to add - // the virtual 'Row #' column which needs a separate unique id for internal use. This id is defined here as -1 in a 16bit integer. - const unsigned int RowNumId = 0xFFFF; + // the virtual 'Row #' column which needs a separate unique id for internal use. This id is defined here as -1. + const int RowNumId = -1; // add columns to x/y selection tree widget if(update) @@ -140,13 +140,11 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett columnitem->setText(PlotColumnType, "Label"); break; } - // maybe i make this more complicated than i should - // but store the model column index in the first 16 bit and the type - // in the other 16 bits - uint itemdata = 0; - itemdata = i << 16; - itemdata |= columntype; - columnitem->setData(PlotColumnField, Qt::UserRole, itemdata); + + // Store the model column index in the PlotColumnField and the type + // in the PlotColumnType, both using the User Role. + columnitem->setData(PlotColumnField, Qt::UserRole, i); + columnitem->setData(PlotColumnType, Qt::UserRole, static_cast(columntype)); columnitem->setText(PlotColumnField, model->headerData(i, Qt::Horizontal).toString()); // restore previous check state @@ -173,10 +171,10 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett { QTreeWidgetItem* columnitem = new QTreeWidgetItem(ui->treePlotColumns); - // Just set all bits in the user role information field here to somehow indicate what column this is - uint itemdata = -1; - columnitem->setData(PlotColumnField, Qt::UserRole, itemdata); + // Just set RowNumId in the user role information field here to somehow indicate what column this is + columnitem->setData(PlotColumnField, Qt::UserRole, RowNumId); columnitem->setText(PlotColumnField, tr("Row #")); + columnitem->setData(PlotColumnType, Qt::UserRole, static_cast(QVariant::Double)); columnitem->setText(PlotColumnType, "Numeric"); // restore previous check state @@ -223,11 +221,9 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett if(xitem) { // regain the model column index and the datatype - // leading 16 bit are column index, the other 16 bit are the datatype - // right now datatype is only important for X axis (date, non date) - uint xitemdata = xitem->data(PlotColumnField, Qt::UserRole).toUInt(); - int x = xitemdata >> 16; - int xtype = xitemdata & (uint)0xFF; + // right now datatype is only important for X axis (Y is always numeric) + int x = xitem->data(PlotColumnField, Qt::UserRole).toInt(); + int xtype = xitem->data(PlotColumnType, Qt::UserRole).toInt(); // check if we have a x axis with datetime data switch (xtype) { @@ -267,10 +263,8 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett QTreeWidgetItem* item = ui->treePlotColumns->topLevelItem(i); if(item->checkState((PlotColumnY)) == Qt::Checked) { - // regain the model column index and the datatype - // leading 16 bit are column index - uint itemdata = item->data(0, Qt::UserRole).toUInt(); - int column = itemdata >> 16; + // regain the model column index + int column = item->data(PlotColumnField, Qt::UserRole).toInt(); bool isSorted = true; @@ -348,7 +342,10 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett QCPBars* bars = new QCPBars(ui->plotWidget->xAxis, ui->plotWidget->yAxis); plottable = bars; bars->setData(xdata, ydata); - bars->setBrush(item->backgroundColor(PlotColumnY)); + QColor brush = item->backgroundColor(PlotColumnY); + if (ui->plotWidget->plottableCount() > 1) + brush.setAlpha(124); + bars->setBrush(brush); QSharedPointer ticker(new QCPAxisTickerText); ticker->addTicks(xdata, labels); ui->plotWidget->xAxis->setTicker(ticker); @@ -376,7 +373,7 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett } plottable->setPen(QPen(item->backgroundColor(PlotColumnY))); - plottable->setSelectable (QCP::stDataRange); + plottable->setSelectable(QCP::stDataRange); // gather Y label column names if(column == RowNumId) @@ -529,8 +526,7 @@ void PlotDock::on_treePlotColumns_itemDoubleClicked(QTreeWidgetItem* item, int c // disable change updates, or we get unwanted redrawing and weird behavior ui->treePlotColumns->blockSignals(true); - uint itemdata = item->data(PlotColumnField, Qt::UserRole).toUInt(); - int type = itemdata & (uint)0xFF; + int type = item->data(PlotColumnType, Qt::UserRole).toInt(); if(column == PlotColumnY && type == QVariant::Double) { diff --git a/src/PlotDock.ui b/src/PlotDock.ui index b9a7e553..d37703af 100644 --- a/src/PlotDock.ui +++ b/src/PlotDock.ui @@ -26,6 +26,9 @@ 2 + + <html><head/><body><p>This pane shows the list of columns of the currently browsed table or the just executed query. You can select the columns that you want to be used as X or Y axis for the plot pane below. The table shows detected axis type that will affect the resulting plot. For the Y axis you can only select numeric columns, but for the X axis you will be able to select:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Date/Time</span>: strings with format &quot;yyyy-MM-dd hh:mm:ss&quot; or &quot;yyyy-MM-ddThh:mm:ss&quot;</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Date</span>: strings with format &quot;yyyy-MM-dd&quot;</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Time</span>: strings with format &quot;hh:mm:ss&quot;</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Label</span>: other string formats. Selecting this column as X axis will produce a Bars plot with the column values as labels for the bars</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Numeric</span>: integer or real values</li></ul><p>Double-clicking the Y cells you can change the used color for that graph.</p></body></html> + true From c5ec23e92e352af5a6220328bda5f28069a26a60 Mon Sep 17 00:00:00 2001 From: mgrojo Date: Sun, 21 Jan 2018 17:00:45 +0100 Subject: [PATCH 3/4] Stacked or grouped bars and plot legend Two new options added to the context menu of the plot: - Stacked bars: switches between stacked bars or grouped bars. The former overlapped layout is avoided since it doesn't make much sense. - Show legend: toggles the display of a plot legend with a translucent background. Possible future improvement is dragging the legend with the mouse. --- src/PlotDock.cpp | 127 ++++++++++++++++++++++++++++++++++++----------- src/PlotDock.h | 6 ++- 2 files changed, 103 insertions(+), 30 deletions(-) diff --git a/src/PlotDock.cpp b/src/PlotDock.cpp index 7e37c1cc..cf9c33d7 100644 --- a/src/PlotDock.cpp +++ b/src/PlotDock.cpp @@ -9,7 +9,9 @@ PlotDock::PlotDock(QWidget* parent) : QDialog(parent), ui(new Ui::PlotDock), m_currentPlotModel(nullptr), - m_currentTableSettings(nullptr) + m_currentTableSettings(nullptr), + m_showLegend(false), + m_stackedBars(false) { ui->setupUi(this); @@ -50,6 +52,18 @@ PlotDock::PlotDock(QWidget* parent) copy(); }); + QAction* showLegendAction = new QAction(tr("Show legend"), m_contextMenu); + showLegendAction->setCheckable(true); + m_contextMenu->addAction(showLegendAction); + + connect(showLegendAction, SIGNAL(toggled(bool)), this, SLOT(toggleLegendVisible(bool))); + + QAction* stackedBarsAction = new QAction(tr("Stacked bars"), m_contextMenu); + stackedBarsAction->setCheckable(true); + m_contextMenu->addAction(stackedBarsAction); + + connect(stackedBarsAction, SIGNAL(toggled(bool)), this, SLOT(toggleStackedBars(bool))); + connect(ui->plotWidget, &QTableView::customContextMenuRequested, [=](const QPoint& pos) { // Show menu @@ -225,6 +239,8 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett int x = xitem->data(PlotColumnField, Qt::UserRole).toInt(); int xtype = xitem->data(PlotColumnType, Qt::UserRole).toInt(); + ui->plotWidget->xAxis->setTickLabelRotation(0); + // check if we have a x axis with datetime data switch (xtype) { case QVariant::Date: { @@ -247,6 +263,8 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett break; } case QVariant::String: { + // Ticker is set when we have got the labels + ui->plotWidget->xAxis->setTickLabelRotation(60); break; } default: { @@ -334,6 +352,7 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett QCPScatterStyle scatterStyle = QCPScatterStyle(static_cast(shapeIdx), 5); QCPAbstractPlottable* plottable; + // When the X type is String, we draw a bar chart. // When it is already sorted by x, we draw a graph. // When it is not sorted by x, we draw a curve, so the order selected by the user in the table or in the query is // respected. In this case the line will have loops and only None and Line is supported as line style. @@ -342,38 +361,39 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett QCPBars* bars = new QCPBars(ui->plotWidget->xAxis, ui->plotWidget->yAxis); plottable = bars; bars->setData(xdata, ydata); - QColor brush = item->backgroundColor(PlotColumnY); - if (ui->plotWidget->plottableCount() > 1) - brush.setAlpha(124); - bars->setBrush(brush); - QSharedPointer ticker(new QCPAxisTickerText); - ticker->addTicks(xdata, labels); - ui->plotWidget->xAxis->setTicker(ticker); - ui->plotWidget->xAxis->setTickLabelRotation(60); - } else if (isSorted) { - QCPGraph* graph = ui->plotWidget->addGraph(); - plottable = graph; - graph->setData(xdata, ydata, /*alreadySorted*/ true); - // set some graph styles not supported by the abstract plottable - graph->setLineStyle((QCPGraph::LineStyle) ui->comboLineType->currentIndex()); - graph->setScatterStyle(scatterStyle); - ui->plotWidget->xAxis->setTickLabelRotation(0); - + // Set ticker once + if (ui->plotWidget->plottableCount() == 1) { + QSharedPointer ticker(new QCPAxisTickerText); + ticker->addTicks(xdata, labels); + ui->plotWidget->xAxis->setTicker(ticker); + } + QColor color = item->backgroundColor(PlotColumnY); + bars->setBrush(color); + plottable->setPen(QPen(color.darker(150))); } else { - QCPCurve* curve = new QCPCurve(ui->plotWidget->xAxis, ui->plotWidget->yAxis); - plottable = curve; - curve->setData(tdata, xdata, ydata, /*alreadySorted*/ true); - // set some curve styles not supported by the abstract plottable - if (ui->comboLineType->currentIndex() == QCPCurve::lsNone) - curve->setLineStyle(QCPCurve::lsNone); - else - curve->setLineStyle(QCPCurve::lsLine); - curve->setScatterStyle(scatterStyle); - ui->plotWidget->xAxis->setTickLabelRotation(0); + if (isSorted) { + QCPGraph* graph = ui->plotWidget->addGraph(); + plottable = graph; + graph->setData(xdata, ydata, /*alreadySorted*/ true); + // set some graph styles not supported by the abstract plottable + graph->setLineStyle((QCPGraph::LineStyle) ui->comboLineType->currentIndex()); + graph->setScatterStyle(scatterStyle); + } else { + QCPCurve* curve = new QCPCurve(ui->plotWidget->xAxis, ui->plotWidget->yAxis); + plottable = curve; + curve->setData(tdata, xdata, ydata, /*alreadySorted*/ true); + // set some curve styles not supported by the abstract plottable + if (ui->comboLineType->currentIndex() == QCPCurve::lsNone) + curve->setLineStyle(QCPCurve::lsNone); + else + curve->setLineStyle(QCPCurve::lsLine); + curve->setScatterStyle(scatterStyle); + } + plottable->setPen(QPen(item->backgroundColor(PlotColumnY))); } - plottable->setPen(QPen(item->backgroundColor(PlotColumnY))); plottable->setSelectable(QCP::stDataRange); + plottable->setName(item->text(PlotColumnField)); // gather Y label column names if(column == RowNumId) @@ -384,6 +404,9 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett } ui->plotWidget->rescaleAxes(true); + ui->plotWidget->legend->setVisible(m_showLegend); + // Legend with slightly transparent background brush: + ui->plotWidget->legend->setBrush(QColor(255, 255, 255, 150)); // set axis labels if(x == RowNumId) @@ -392,6 +415,8 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett ui->plotWidget->xAxis->setLabel(model->headerData(x, Qt::Horizontal).toString()); ui->plotWidget->yAxis->setLabel(yAxisLabels.join("|")); } + + adjustBars(); ui->plotWidget->replot(); // Warn user if not all data has been fetched and hint about the button for loading all the data @@ -789,3 +814,47 @@ void PlotDock::copy() { QApplication::clipboard()->setPixmap(ui->plotWidget->toPixmap()); } + +void PlotDock::toggleLegendVisible(bool visible) +{ + m_showLegend = visible; + ui->plotWidget->legend->setVisible(m_showLegend); + ui->plotWidget->replot(); +} + +// Stack or group bars and set the appropiate bar width (since it is not automatically done by QCustomPlot). +void PlotDock::adjustBars() +{ + const double padding = 0.15; + const double groupedWidth = ui->plotWidget->plottableCount()? 1.0 / ui->plotWidget->plottableCount() : 0.0; + QCPBars* previousBar = nullptr; + QCPBarsGroup* barsGroup = m_stackedBars? nullptr : new QCPBarsGroup(ui->plotWidget); + for (int i = 0, ie = ui->plotWidget->plottableCount(); i < ie; ++i) + { + QCPBars* bar = qobject_cast(ui->plotWidget->plottable(i)); + if (bar) { + if (m_stackedBars) { + // Ungroup if grouped + bar->setBarsGroup(nullptr); + if (previousBar) + bar->moveAbove(previousBar); + // Set width to ocuppy the full coordinate space, less padding + bar->setWidth(1.0 - padding); + } else { + // Unstack if stacked + bar->moveAbove(nullptr); + bar->setBarsGroup(barsGroup); + // Set width to a plot coordinate width, less padding + bar->setWidth(groupedWidth - padding); + } + previousBar = bar; + } + } +} + +void PlotDock::toggleStackedBars(bool stacked) +{ + m_stackedBars = stacked; + adjustBars(); + ui->plotWidget->replot(); +} diff --git a/src/PlotDock.h b/src/PlotDock.h index 6acc02dd..11631582 100644 --- a/src/PlotDock.h +++ b/src/PlotDock.h @@ -85,6 +85,8 @@ private: SqliteTableModel* m_currentPlotModel; BrowseDataTableSettings* m_currentTableSettings; QMenu* m_contextMenu; + bool m_showLegend; + bool m_stackedBars; /*! * \brief guessdatatype try to parse the first 10 rows and decide the datatype @@ -93,6 +95,7 @@ private: * \return the guessed datatype */ QVariant::Type guessDataType(SqliteTableModel* model, int column); + void adjustBars(); private slots: void on_treePlotColumns_itemChanged(QTreeWidgetItem* item, int column); @@ -104,7 +107,8 @@ private slots: void mousePress(); void mouseWheel(); void copy(); - + void toggleLegendVisible(bool visible); + void toggleStackedBars(bool stacked); }; #endif From 42bb1c0d65dec158c0c83ba32764b85031598f5c Mon Sep 17 00:00:00 2001 From: mgrojo Date: Fri, 26 Jan 2018 18:13:20 +0100 Subject: [PATCH 4/4] Translatable strings and default case branch This addresses review comments by @MKleusberg in PR #1302. --- src/PlotDock.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/PlotDock.cpp b/src/PlotDock.cpp index cf9c33d7..3f382fa7 100644 --- a/src/PlotDock.cpp +++ b/src/PlotDock.cpp @@ -139,20 +139,23 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett switch (columntype) { case QVariant::DateTime: - columnitem->setText(PlotColumnType, "Date/Time"); + columnitem->setText(PlotColumnType, tr("Date/Time")); break; case QVariant::Date: - columnitem->setText(PlotColumnType, "Date"); + columnitem->setText(PlotColumnType, tr("Date")); break; case QVariant::Time: - columnitem->setText(PlotColumnType, "Time"); + columnitem->setText(PlotColumnType, tr("Time")); break; case QVariant::Double: - columnitem->setText(PlotColumnType, "Numeric"); + columnitem->setText(PlotColumnType, tr("Numeric")); break; case QVariant::String: - columnitem->setText(PlotColumnType, "Label"); + columnitem->setText(PlotColumnType, tr("Label")); break; + default: + // This is not actually expected + columnitem->setText(PlotColumnType, tr("Invalid")); } // Store the model column index in the PlotColumnField and the type @@ -189,7 +192,7 @@ void PlotDock::updatePlot(SqliteTableModel* model, BrowseDataTableSettings* sett columnitem->setData(PlotColumnField, Qt::UserRole, RowNumId); columnitem->setText(PlotColumnField, tr("Row #")); columnitem->setData(PlotColumnType, Qt::UserRole, static_cast(QVariant::Double)); - columnitem->setText(PlotColumnType, "Numeric"); + columnitem->setText(PlotColumnType, tr("Numeric")); // restore previous check state if(mapItemsY.contains(columnitem->text(PlotColumnField)))