123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- #include "pch.h"
- #include "GraphPlott.h"
- #include <QDebug>
- #include <QPen>
- #include <QPushButton>
- #include <QLayout>
- #include <QHBoxLayout>
- #include <QVBoxLayout>
- #include "HoverButton.h"
- #include <QApplication>
- #include <QDesktopWidget>
- GraphPlott::GraphPlott(QWidget* parent, bool showSettingsButton, bool showInformationButton, bool showGridButton)
- : Plott(parent)
- {
- QVBoxLayout* layoutOuter = new QVBoxLayout(this);
- buttonPanel = new QHBoxLayout();
- dialog = new GraphViewSettingDialog(this, "Settings");
- this->setMouseTracking(true);
- buttonPanel->insertStretch(0);
- displayLabel = new QLabel("");
- buttonPanel->addWidget(displayLabel);
- HoverButton* frameButton = new HoverButton();
- frameButton->setMinimumSize(20, 20);
- frameButton->setMaximumSize(20, 20);
- frameButton->setIcon(QIcon(":/metavis/Resources/frame.svg"));
- frameButton->setHoveredIcon(QIcon(":/metavis/Resources/frame_hovered.svg"));
- frameButton->setAttribute(Qt::WA_TranslucentBackground);
- frameButton->setStyleSheet(frameButton->styleSheet() + "border: none;");
- frameButton->setToolTip("Frame");
- buttonPanel->addWidget(frameButton);
- connect(frameButton, &QPushButton::released, this, &GraphPlott::frameGraphInView);
- if (showGridButton) {
- HoverButton* gridButton = new HoverButton();
- gridButton->setMinimumSize(20, 20);
- gridButton->setMaximumSize(20, 20);
- gridButton->setIcon(QIcon(":/metavis/Resources/gridIcon.svg"));
- gridButton->setHoveredIcon(QIcon(":/metavis/Resources/gridIcon_hovered.svg"));
- gridButton->setAttribute(Qt::WA_TranslucentBackground);
- gridButton->setStyleSheet(gridButton->styleSheet() + "border: none;");
- gridButton->setToolTip("Toggle Grid");
- buttonPanel->addWidget(gridButton);
- connect(gridButton, &QPushButton::released, this, [this]() {this->enableGrid = !this->enableGrid; update(); });
- }
- if (showInformationButton) {
-
- informationButton->setMinimumSize(20, 20);
- informationButton->setMaximumSize(20, 20);
- informationButton->setIcon(QIcon(":/metavis/Resources/information_icon.svg"));
- informationButton->setHoveredIcon(QIcon(":/metavis/Resources/information_icon_hovered.svg"));
- informationButton->setAttribute(Qt::WA_TranslucentBackground);
- informationButton->setStyleSheet(informationButton->styleSheet() + "border: none;");
- informationButton->setToolTip("Information");
- connect(informationButton, &QPushButton::released, this, &GraphPlott::showInformation);
- buttonPanel->addWidget(informationButton);
- }
-
- if (showSettingsButton) {
- HoverButton* settingsButton = new HoverButton();
- settingsButton->setMinimumSize(20, 20);
- settingsButton->setMaximumSize(20, 20);
- settingsButton->setIcon(QIcon(":/metavis/Resources/settingIcon.svg"));
- settingsButton->setHoveredIcon(QIcon(":/metavis/Resources/settingIcon_hovered.svg"));
- settingsButton->setAttribute(Qt::WA_TranslucentBackground);
- settingsButton->setStyleSheet(settingsButton->styleSheet() + "border: none;");
- settingsButton->setToolTip("Settings");
- buttonPanel->addWidget(settingsButton);
- connect(settingsButton, &QPushButton::released, dialog, &GraphViewSettingDialog::openDialog);
- }
- buttonPanel->setSpacing(0);
- buttonPanel->setContentsMargins(0, 0, 0, 0);
- layoutOuter->addLayout(buttonPanel);
- layoutOuter->insertStretch(1);
- layoutOuter->setContentsMargins(0, 0, 0, 0);
- //QMenu
- selectMenu->addAction(displayAreaAction);
- selectMenu->addAction(scratchpadAction);
- displayAreaAction->setShortcut(QKeySequence(Qt::CTRL));
- scratchpadAction->setShortcut(QKeySequence(Qt::ALT));
- scratchpadAction->setEnabled(false);
- //setUpTimer
- timer->setSingleShot(true);
- connect(timer, &QTimer::timeout, this, &GraphPlott::searchForPointUnderCursor);
- }
- GraphPlott::~GraphPlott()
- {
- }
- void GraphPlott::addSeries(std::vector<GraphDataPoint>* line, std::string runName, QString description, QColor color, GraphPlottSeries::SeriesType type)
- {
- if (line->empty()) {
- qDebug() << "Series is empty!";
- return;
- }
- GraphPlottSeries lgs;
- lgs.runName = runName;
- lgs.description = description;
- lgs.data = line;
- lgs.type = type;
- lgs.color = color;
- //set min max x y
- auto pairX = std::minmax_element(lgs.data->begin(), lgs.data->end(), [](const GraphDataPoint& a, const GraphDataPoint& b) -> bool {return a.x < b.x; });
- lgs.xMin = pairX.first->x;
- lgs.xMax = pairX.second->x;
- auto pairY = std::minmax_element(lgs.data->begin(), lgs.data->end(), [](const GraphDataPoint& a, const GraphDataPoint& b) -> bool {return a.y < b.y; });
- lgs.yMin = pairY.first->y;
- lgs.yMax = pairY.second->y;
- seriesVec.push_back(lgs);
- }
- void GraphPlott::removeRunData(RunData* run)
- {
- //Remove all series with this rundata
- auto iter = std::remove_if(seriesVec.begin(), seriesVec.end(), [run](GraphPlottSeries& series) {return (run->name == series.runName); });
- seriesVec.erase(iter, seriesVec.end());
- displayLabel->setText("");
- }
- void GraphPlott::removeAll()
- {
- seriesVec.clear();
- }
- void GraphPlott::setInformation(QString information)
- {
- this->informationButtonString = information;
- popupWidget->setInformation(information);
- }
- std::vector<GraphPlottSeries>& GraphPlott::getSeriesVector()
- {
- return seriesVec;
- }
- void GraphPlott::resetToDefaultWindow()
- {
- frameGraphInView();
- }
- void GraphPlott::frameGraphInView()
- {
- if(seriesVec.empty()) return;
- window.xMin = std::min_element(std::begin(seriesVec), std::end(seriesVec), [](const GraphPlottSeries& a, const GraphPlottSeries& b) -> bool {return a.xMin < b.xMin; })->xMin;
- window.xMax = std::max_element(std::begin(seriesVec), std::end(seriesVec), [](const GraphPlottSeries& a, const GraphPlottSeries& b) -> bool {return a.xMax < b.xMax; })->xMax;
- window.yMin = std::min_element(std::begin(seriesVec), std::end(seriesVec), [](const GraphPlottSeries& a, const GraphPlottSeries& b) -> bool {return a.yMin < b.yMin; })->yMin;
- window.yMax = std::max_element(std::begin(seriesVec), std::end(seriesVec), [](const GraphPlottSeries& a, const GraphPlottSeries& b) -> bool {return a.yMax < b.yMax; })->yMax;
- window.ZoomOut(0.05);
- update();
- }
- void GraphPlott::setDisplayLabel(QString file)
- {
- displayLabel->setText("\"" + file + "\" ");
- }
- void GraphPlott::setScratchpad(Scratchpad* pad)
- {
- this->pad = pad;
- scratchpadAction->setEnabled(true);
- }
- void GraphPlott::showInformation()
- {
- QPoint position = QCursor::pos();
- popupWidget->setInformation(informationButtonString + graphplottInformation);
- popupWidget->width();
- QRect screen = QApplication::desktop()->screenGeometry();
- if (position.x() + popupWidget->width() > screen.width()) {
- popupWidget->move(screen.width() - popupWidget->width(), position.y());
- }
- else {
- popupWidget->move(position.x(), position.y());
- }
- popupWidget->show();
- }
- void GraphPlott::drawData(QPainter& painter)
- {
- QPen linePen;
- QRect graphDisplayRect = getDisplayRect();
- QPointF translation(graphDisplayRect.left(), graphDisplayRect.top());
- double stregth_factorX = graphDisplayRect.width() / std::abs(window.xMax - window.xMin);
- double stregth_factorY = graphDisplayRect.height() / std::abs(window.yMax - window.yMin);
- for (const GraphPlottSeries& graphSeries : seriesVec) {
- if (!graphSeries.data) {
- qDebug() << "Pointer to nothing pls help";
- }
- if (graphSeries.data->empty() || graphSeries.hide) continue;
- linePen.setColor(graphSeries.color);
- if (graphSeries.type == GraphPlottSeries::SeriesType::Line || graphSeries.type == GraphPlottSeries::SeriesType::LineDot) {
- linePen.setWidth(graphSeries.lineWidth/* + ((&graphSeries == highlightSeries) ? 5 : 0)*/);
- painter.setPen(linePen);
- QPainterPath painterPath;
- QPointF oldpoint = graphSeries.data->at(0).toQPointF();
- painterPath.moveTo(transformGraphToView(oldpoint, stregth_factorX, stregth_factorY, translation));
- for (int i = 1; i < graphSeries.data->size(); i++) {
- QPointF newpoint = graphSeries.data->at(i).toQPointF();
- bool inBoundOldPoint = window.inBoundX(oldpoint);
- bool inBoundNewPoint = window.inBoundX(newpoint);
- if (!inBoundOldPoint && !inBoundNewPoint) {
- }
- else if (!inBoundOldPoint && inBoundNewPoint) {
- painterPath.moveTo(transformGraphToView(oldpoint, stregth_factorX, stregth_factorY, translation));
- painterPath.lineTo(transformGraphToView(newpoint, stregth_factorX, stregth_factorY, translation));
- }
- else if (inBoundOldPoint && inBoundNewPoint) {
- painterPath.lineTo(transformGraphToView(newpoint, stregth_factorX, stregth_factorY, translation));
- }
- else if (inBoundOldPoint && !inBoundNewPoint) {
- painterPath.lineTo(transformGraphToView(newpoint, stregth_factorX, stregth_factorY, translation));
- break;
- }
- oldpoint = newpoint;
- }
- //painterPath.translate(translation);
- painter.drawPath(painterPath);
- }
- if (graphSeries.type == GraphPlottSeries::SeriesType::Dot || graphSeries.type == GraphPlottSeries::SeriesType::LineDot) {
- linePen.setWidth(2);
- linePen.setColor(Qt::transparent);
- painter.setPen(linePen);
- painter.setBrush(graphSeries.color);
- const bool useColor = graphSeries.useDataPointColor;
- for (auto data : *graphSeries.data) {
- if (useColor){
- linePen.setColor(data.color);
- painter.setPen(linePen);
- painter.setBrush(data.color);
- }
- if (window.inBound(data.toQPointF())) {
- painter.drawEllipse(transformGraphToView(data.toQPointF(), stregth_factorX, stregth_factorY, translation), graphSeries.circleRadius, graphSeries.circleRadius);
- }
- }
- painter.setBrush(Qt::BrushStyle::NoBrush);
- }
- }
- }
- void GraphPlott::mouseMoveEvent(QMouseEvent* event)
- {
- Plott::mouseMoveEvent(event);
- lastPosition = event->pos();
- timer->start(stayStillTimeMS);
- QToolTip::hideText();
- }
- void GraphPlott::handleSelectedWindow(VisibleWindow& window, QMouseEvent* event)
- {
- if (event->modifiers() & Qt::ControlModifier) {
- setWindow(window);
- }
- else if (event->modifiers() & Qt::AltModifier) {
- addPointsInWindowToScratchPad(window);
- }
- else {
- QAction* used = selectMenu->exec(this->mapToGlobal(event->pos()));
- if(used == displayAreaAction){
- setWindow(window);
- }
- else if (used == scratchpadAction) {
- addPointsInWindowToScratchPad(window);
- }
- }
-
- }
- void GraphPlott::searchForPointUnderCursor()
- {
- //check if mouse stayed still
- QPoint globalPosition = QCursor::pos();
- QPointF pos = this->mapFromGlobal(globalPosition);
- if (pos != lastPosition) {
- return;
- }
- if (seriesVec.empty() || seriesVec[0].data->empty()) {
- return;
- }
- QRect graphDisplayRect = getDisplayRect();
- QPointF translation(graphDisplayRect.left(), graphDisplayRect.top());
- double stregth_factorX = graphDisplayRect.width() / std::abs(window.xMax - window.xMin);
- double stregth_factorY = graphDisplayRect.height() / std::abs(window.yMax - window.yMin);
- const GraphDataPoint* min = &seriesVec[0].data->at(0);
- double minSqaredDistance = sqaredDistance(transformGraphToView(min->toQPointF(), stregth_factorX, stregth_factorY, translation), pos);
- std::vector<GraphPlottSeries>::iterator actualBestSeries = seriesVec.begin();
- for (auto seriesIter = seriesVec.begin(); seriesIter != seriesVec.end(); seriesIter++) {
- for (const GraphDataPoint& point : *seriesIter->data) {
- double distance = sqaredDistance(transformGraphToView(point.toQPointF(), stregth_factorX, stregth_factorY, translation), pos);
- if (distance <= minSqaredDistance) {
- minSqaredDistance = distance;
- min = &point;
- actualBestSeries = seriesIter;
- }
- }
- }
- if (minSqaredDistance <= 20) {
- QPointF pointInWidget = transformGraphToView(min->toQPointF(), stregth_factorX, stregth_factorY, translation);
- QToolTip::showText(this->mapToGlobal(QPoint(pointInWidget.x(), pointInWidget.y())) - QPoint(0, 35), actualBestSeries->description);
- }
- }
- double GraphPlott::sqaredDistance(const QPointF& a, const QPointF& b)
- {
- return std::pow(a.x() - b.x(), 2) + std::pow(a.y() - b.y(), 2);
- }
- void GraphPlott::addPointsInWindowToScratchPad(VisibleWindow& window)
- {
- if (!pad) {
- qDebug() << "NoPad";
- return;
- }
- for (auto seriesIter = seriesVec.begin(); seriesIter != seriesVec.end(); seriesIter++) {
- if (seriesIter->hide) continue;
- for (const GraphDataPoint& point : *seriesIter->data) {
- if (window.inBound(point.toQPointF()) && point.existLink()) {
- pad->addPoint(*point.orginalPoint);
- }
- }
- }
- }
- void GraphPlott::keyPressEvent(QKeyEvent* event)
- {
- Plott::keyPressEvent(event);
- switch (event->key()) {
- case Qt::Key_T:
- frameGraphInView();
- break;
- default:
- break;
- }
- }
|