/*Copyright © 2018 Hasan Yavuz ÖzderyaThis file is part of serialplot.serialplot is free software: you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation, either version 3 of the License, or(at your option) any later version.serialplot is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with serialplot. If not, see <http://www.gnu.org/licenses/>.*/#include <algorithm>#include <QMetaEnum>#include <QtDebug>#include "qwt_symbol.h"#include "plot.h"#include "plotmanager.h"#include "utils.h"#include "setting_defines.h"PlotManager::PlotManager(QWidget* plotArea, PlotMenu* menu,ChannelInfoModel* infoModel, QObject* parent) :QObject(parent){_menu = menu;_plotArea = plotArea;_autoScaled = true;_yMin = 0;_yMax = 1;_xAxisAsIndex = true;isDemoShown = false;_infoModel = infoModel;_numOfSamples = 1;_plotWidth = 1;showSymbols = Plot::ShowSymbolsAuto;emptyPlot = NULL;// initalize layout and single widgetisMulti = false;scrollArea = NULL;setupLayout(isMulti);addPlotWidget();// connect to menuconnect(menu, &PlotMenu::symbolShowChanged, this, &PlotManager:: setSymbols);connect(&menu->showGridAction, SELECT<bool>::OVERLOAD_OF(&QAction::toggled),this, &PlotManager::showGrid);connect(&menu->showMinorGridAction, SELECT<bool>::OVERLOAD_OF(&QAction::toggled),this, &PlotManager::showMinorGrid);connect(&menu->darkBackgroundAction, SELECT<bool>::OVERLOAD_OF(&QAction::toggled),this, &PlotManager::darkBackground);connect(&menu->showLegendAction, SELECT<bool>::OVERLOAD_OF(&QAction::toggled),this, &PlotManager::showLegend);connect(&menu->showMultiAction, SELECT<bool>::OVERLOAD_OF(&QAction::toggled),this, &PlotManager::setMulti);connect(&menu->unzoomAction, &QAction::triggered,this, &PlotManager::unzoom);// initial settings from menu actionsshowGrid(menu->showGridAction.isChecked());showMinorGrid(menu->showMinorGridAction.isChecked());darkBackground(menu->darkBackgroundAction.isChecked());showLegend(menu->showLegendAction.isChecked());setMulti(menu->showMultiAction.isChecked());// connect to channel info modelif (_infoModel != NULL) // TODO: remove when snapshots have infomodel{connect(_infoModel, &QAbstractItemModel::dataChanged,this, &PlotManager::onChannelInfoChanged);connect(_infoModel, &QAbstractItemModel::modelReset,[this](){onChannelInfoChanged(_infoModel->index(0, 0), // start_infoModel->index(_infoModel->rowCount()-1, 0), // end{}); // roles ignored});}}PlotManager::~PlotManager(){while (curves.size()){delete curves.takeLast();}// remove all widgetswhile (plotWidgets.size()){delete plotWidgets.takeLast();}if (scrollArea != NULL) delete scrollArea;if (emptyPlot != NULL) delete emptyPlot;}void PlotManager::onChannelInfoChanged(const QModelIndex &topLeft,const QModelIndex &bottomRight,const QVector<int> &roles){int start = topLeft.row();int end = bottomRight.row();for (int ci = start; ci <= end; ci++){QString name = topLeft.sibling(ci, ChannelInfoModel::COLUMN_NAME).data(Qt::EditRole).toString();QColor color = topLeft.sibling(ci, ChannelInfoModel::COLUMN_NAME).data(Qt::ForegroundRole).value<QColor>();bool visible = topLeft.sibling(ci, ChannelInfoModel::COLUMN_VISIBILITY).data(Qt::CheckStateRole).toBool();curves[ci]->setTitle(name);curves[ci]->setPen(color);curves[ci]->setVisible(visible);curves[ci]->setItemAttribute(QwtPlotItem::Legend, visible);// replot only updated widgetsif (isMulti){plotWidgets[ci]->updateSymbols(); // required for color changeplotWidgets[ci]->updateLegend(curves[ci]);plotWidgets[ci]->setVisible(visible);if (visible){plotWidgets[ci]->replot();}}}checkNoVisChannels();// replot single widgetif (!isMulti){plotWidgets[0]->updateSymbols();plotWidgets[0]->updateLegend();replot();}}void PlotManager::checkNoVisChannels(){// if all channels are hidden show indicatorbool allhidden = std::none_of(curves.cbegin(), curves.cend(),[](QwtPlotCurve* c) {return c->isVisible();});plotWidgets[0]->showNoChannel(allhidden);if (isMulti){plotWidgets[0]->showNoChannel(allhidden);plotWidgets[0]->setVisible(true);}}void PlotManager::setMulti(bool enabled){if (enabled == isMulti) return;isMulti = enabled;// detach all curvesfor (auto curve : curves){curve->detach();}// remove all widgetswhile (plotWidgets.size()){delete plotWidgets.takeLast();}// setup new layoutsetupLayout(isMulti);if (isMulti){// add new widgets and attachfor (auto curve : curves){auto plot = addPlotWidget();plot->setVisible(curve->isVisible());curve->attach(plot);}}else{// add a single widgetauto plot = addPlotWidget();// attach all curvesfor (auto curve : curves){curve->attach(plot);}}// will skip if no plot widgets exist (can happen during constructor)if (plotWidgets.length()){checkNoVisChannels();}}void PlotManager::setupLayout(bool multiPlot){// delete previous layout if it existsif (_plotArea->layout() != 0){delete _plotArea->layout();}if (multiPlot){// setup a scroll areascrollArea = new QScrollArea();auto scrolledPlotArea = new QWidget(scrollArea);scrollArea->setWidget(scrolledPlotArea);scrollArea->setWidgetResizable(true);_plotArea->setLayout(new QVBoxLayout());_plotArea->layout()->addWidget(scrollArea);_plotArea->layout()->setContentsMargins(0,0,0,0);layout = new QVBoxLayout(scrolledPlotArea);}else{// delete scrollArea left from multi layoutif (scrollArea != NULL){delete scrollArea;scrollArea = NULL;}layout = new QVBoxLayout(_plotArea);}layout->setContentsMargins(2,2,2,2);layout->setSpacing(1);}Plot* PlotManager::addPlotWidget(){auto plot = new Plot();plotWidgets.append(plot);layout->addWidget(plot);plot->darkBackground(_menu->darkBackgroundAction.isChecked());plot->showGrid(_menu->showGridAction.isChecked());plot->showMinorGrid(_menu->showMinorGridAction.isChecked());plot->showLegend(_menu->showLegendAction.isChecked());plot->setSymbols(_menu->showSymbols());plot->showDemoIndicator(isDemoShown);plot->setYAxis(_autoScaled, _yMin, _yMax);plot->setNumOfSamples(_numOfSamples);plot->setPlotWidth(_plotWidth);if (_xAxisAsIndex){plot->setXAxis(0, _numOfSamples);}else{plot->setXAxis(_xMin, _xMax);}return plot;}void PlotManager::addCurve(QString title, FrameBuffer* buffer){auto curve = new QwtPlotCurve(title);auto series = new FrameBufferSeries(buffer);series->setXAxis(_xAxisAsIndex, _xMin, _xMax);curve->setSamples(series);_addCurve(curve);}void PlotManager::addCurve(QString title, QVector<QPointF> data){auto curve = new QwtPlotCurve(title);curve->setSamples(data);_addCurve(curve);}void PlotManager::_addCurve(QwtPlotCurve* curve){// store and init the curvecurves.append(curve);unsigned index = curves.size()-1;auto color = _infoModel->color(index);curve->setPen(color);// create the plot for the curve if we are on multi displayPlot* plot;if (isMulti){// create a new plot widgetplot = addPlotWidget();}else{plot = plotWidgets[0];}// show the curvecurve->attach(plot);plot->replot();}void PlotManager::removeCurves(unsigned number){for (unsigned i = 0; i < number; i++){if (!curves.isEmpty()){delete curves.takeLast();if (isMulti) // delete corresponding widget as well{delete plotWidgets.takeLast();}}}}unsigned PlotManager::numOfCurves(){return curves.size();}Plot* PlotManager::plotWidget(unsigned curveIndex){if (isMulti){return plotWidgets[curveIndex];}else{return plotWidgets[0];}}void PlotManager::replot(){for (auto plot : plotWidgets){plot->replot();}}void PlotManager::showGrid(bool show){for (auto plot : plotWidgets){plot->showGrid(show);}}void PlotManager::showMinorGrid(bool show){for (auto plot : plotWidgets){plot->showMinorGrid(show);}}void PlotManager::showLegend(bool show){for (auto plot : plotWidgets){plot->showLegend(show);}}void PlotManager::showDemoIndicator(bool show){isDemoShown = show;for (auto plot : plotWidgets){plot->showDemoIndicator(show);}}void PlotManager::unzoom(){for (auto plot : plotWidgets){plot->unzoom();}}void PlotManager::darkBackground(bool enabled){for (auto plot : plotWidgets){plot->darkBackground(enabled);}}void PlotManager::setSymbols(Plot::ShowSymbols shown){showSymbols = shown;for (auto plot : plotWidgets){plot->setSymbols(shown);}}void PlotManager::setYAxis(bool autoScaled, double yAxisMin, double yAxisMax){_autoScaled = autoScaled;_yMin = yAxisMin;_yMax = yAxisMax;for (auto plot : plotWidgets){plot->setYAxis(autoScaled, yAxisMin, yAxisMax);}}void PlotManager::setXAxis(bool asIndex, double xMin, double xMax){_xAxisAsIndex = asIndex;_xMin = xMin;_xMax = xMax;for (auto curve : curves){// TODO: what happens when addCurve(QVector) is used?FrameBufferSeries* series = static_cast<FrameBufferSeries*>(curve->data());series->setXAxis(asIndex, xMin, xMax);}for (auto plot : plotWidgets){if (asIndex){plot->setXAxis(0, _numOfSamples);}else{plot->setXAxis(xMin, xMax);}}replot();}void PlotManager::flashSnapshotOverlay(){for (auto plot : plotWidgets){plot->flashSnapshotOverlay(_menu->darkBackgroundAction.isChecked());}}void PlotManager::setNumOfSamples(unsigned value){_numOfSamples = value;for (auto plot : plotWidgets){plot->setNumOfSamples(value);if (_xAxisAsIndex) plot->setXAxis(0, value);}}void PlotManager::setPlotWidth(double width){_plotWidth = width;for (auto plot : plotWidgets){plot->setPlotWidth(width);}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。