On the fermenter, iSpindel, carbonation and brewday chart a tooltip with values is shown wheren hovering over the most important data lines. Changed the vertical to horzontal screen layout and added a save button to save the graph as .png image.

Tue, 26 Jul 2022 14:26:50 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Tue, 26 Jul 2022 14:26:50 +0200
changeset 371
d03a426e0b6b
parent 370
a730825bc5e4
child 372
d9c78eb19728

On the fermenter, iSpindel, carbonation and brewday chart a tooltip with values is shown wheren hovering over the most important data lines. Changed the vertical to horzontal screen layout and added a save button to save the graph as .png image.

src/ChartCarbonate.cpp file | annotate | diff | comparison | revisions
src/ChartCarbonate.h file | annotate | diff | comparison | revisions
src/ChartFermenter.cpp file | annotate | diff | comparison | revisions
src/ChartFermenter.h file | annotate | diff | comparison | revisions
src/ChartiSpindel.cpp file | annotate | diff | comparison | revisions
src/ChartiSpindel.h file | annotate | diff | comparison | revisions
src/EditProduct.cpp file | annotate | diff | comparison | revisions
src/EditProduct.h file | annotate | diff | comparison | revisions
src/EditProductTab9.cpp file | annotate | diff | comparison | revisions
--- a/src/ChartCarbonate.cpp	Tue Jul 26 11:15:37 2022 +0200
+++ b/src/ChartCarbonate.cpp	Tue Jul 26 14:26:50 2022 +0200
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include "ChartCarbonate.h"
+#include "callout.h"
 #include "MainWindow.h"
 
 
@@ -31,16 +32,20 @@
     dialog->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
     dialog->resize(1024, 600);
 
+    QPushButton *saveButton = new QPushButton(tr("Save"));
+    saveButton->setAutoDefault(false);
+    QIcon icon1;
+    icon1.addFile(QString::fromUtf8(":icons/silk/disk.png"), QSize(), QIcon::Normal, QIcon::Off);
+    saveButton->setIcon(icon1);
+
     QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog);
     buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
-    buttonBox->setGeometry(QRect(40, 565, 944, 36));
-    buttonBox->setLayoutDirection(Qt::LeftToRight);
-    buttonBox->setOrientation(Qt::Horizontal);
+    buttonBox->setOrientation(Qt::Vertical);
     buttonBox->setStandardButtons(QDialogButtonBox::Ok);
-    buttonBox->setCenterButtons(true);
+    buttonBox->addButton(saveButton,QDialogButtonBox::ActionRole);
 
-    QSplineSeries *temperature = new QSplineSeries();
-    QSplineSeries *pressure = new QSplineSeries();
+    temperature = new QSplineSeries();
+    pressure = new QSplineSeries();
 
     query.prepare("SELECT * FROM log_co2pressure WHERE code=:code ORDER BY datetime");
     query.bindValue(":code", code);
@@ -58,7 +63,7 @@
     pen.setWidth(3);
     pressure->setPen(pen);
 
-    QChart *chart = new QChart();
+    chart = new QChart();
     chart->setTitle(QString("%1 \"%2\"").arg(code).arg(name));
     chart->addSeries(temperature);
     chart->addSeries(pressure);
@@ -90,14 +95,20 @@
     chart->addAxis(axisYP, Qt::AlignLeft);
     pressure->attachAxis(axisYP);
 
-    QChartView *chartView = new QChartView(chart);
+    chart->setAcceptHoverEvents(true);
+
+    connect(temperature, &QSplineSeries::hovered, this, &ChartCarbonate::tooltip);
+    connect(pressure, &QSplineSeries::hovered, this, &ChartCarbonate::tooltip);
+
+    chartView = new QChartView(chart);
     chartView->setRenderHint(QPainter::Antialiasing);
-    dialog->setLayout(new QVBoxLayout);
+    dialog->setLayout(new QHBoxLayout);
     dialog->layout()->addWidget(chartView);
     dialog->layout()->addWidget(buttonBox);
 
     QObject::connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
     QObject::connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
+    QObject::connect(saveButton, SIGNAL(clicked()), this, SLOT(savePNG()));
 
     dialog->setModal(true);
     dialog->exec();
@@ -106,3 +117,43 @@
 
 ChartCarbonate::~ChartCarbonate() {}
 
+
+void ChartCarbonate::savePNG()
+{
+    QString path = QFileDialog::getSaveFileName(this, tr("Save Image"), QDir::homePath() + "/carbonation.png", tr("Image (*.png)"));
+    if (path.isEmpty()) {
+	QMessageBox::warning(this, tr("Save File"), tr("No image file selected."));
+	return;
+    }
+
+    QImage img((chartView->size()), QImage::Format_ARGB32);
+    QPainter painter;
+    painter.begin(&img);
+    chartView->render(&painter);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.end();
+    img.save(path);
+}
+
+
+void ChartCarbonate::tooltip(QPointF point, bool state)
+{
+    QAbstractSeries *series = qobject_cast<QAbstractSeries *>(sender());
+
+    if (t_tooltip == 0)
+        t_tooltip = new Callout(chart, series);
+
+    if (state) {
+	QDateTime timeis = QDateTime::fromMSecsSinceEpoch(point.x());
+	QString suffix = (series == temperature) ? "°C":" bar";
+	t_tooltip->setSeries(series);
+	t_tooltip->setText(QString("%1\n%2%3").arg(timeis.toString("dd-MM-yyyy hh:mm")).arg(point.y(), 2, 'f', 1).arg(suffix));
+	t_tooltip->setAnchor(point);
+	t_tooltip->setZValue(11);
+	t_tooltip->updateGeometry();
+	t_tooltip->show();
+    } else {
+	t_tooltip->hide();
+    }
+}
+
--- a/src/ChartCarbonate.h	Tue Jul 26 11:15:37 2022 +0200
+++ b/src/ChartCarbonate.h	Tue Jul 26 14:26:50 2022 +0200
@@ -1,9 +1,12 @@
 #ifndef _CHARTCARBONATE_H
 #define _CHARTCARBONATE_H
 
+#include "MainWindow.h"
+
 #include <QDialog>
 #include <QDialogButtonBox>
 
+class Callout;
 
 namespace Ui {
 class ChartCarbonate;
@@ -13,10 +16,21 @@
 {
     Q_OBJECT
 
+private slots:
+    void savePNG();
+
+public slots:
+    void tooltip(QPointF point, bool state);
+
 public:
     explicit ChartCarbonate(QString code, QString name, QWidget *parent = 0);
     ~ChartCarbonate();
 
+private:
+    QChartView *chartView;
+    QChart *chart;
+    Callout *t_tooltip = 0;
+    QSplineSeries *temperature, *pressure;
 };
 
 #endif
--- a/src/ChartFermenter.cpp	Tue Jul 26 11:15:37 2022 +0200
+++ b/src/ChartFermenter.cpp	Tue Jul 26 14:26:50 2022 +0200
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include "ChartFermenter.h"
+#include "callout.h"
 #include "MainWindow.h"
 
 
@@ -31,13 +32,17 @@
     dialog->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
     dialog->resize(1024, 600);
 
+    QPushButton *saveButton = new QPushButton(tr("Save"));
+    saveButton->setAutoDefault(false);
+    QIcon icon1;
+    icon1.addFile(QString::fromUtf8(":icons/silk/disk.png"), QSize(), QIcon::Normal, QIcon::Off);
+    saveButton->setIcon(icon1);
+
     QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog);
     buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
-    buttonBox->setGeometry(QRect(40, 565, 944, 36));
-    buttonBox->setLayoutDirection(Qt::LeftToRight);
-    buttonBox->setOrientation(Qt::Horizontal);
+    buttonBox->setOrientation(Qt::Vertical);
     buttonBox->setStandardButtons(QDialogButtonBox::Ok);
-    buttonBox->setCenterButtons(true);
+    buttonBox->addButton(saveButton,QDialogButtonBox::ActionRole);
 
     QSplineSeries *pv_air = new QSplineSeries();
     QSplineSeries *pv_beer = new QSplineSeries();
@@ -75,7 +80,7 @@
     pwr_heat->setOpacity(0.25);
     pwr_heat->setColor(QColorConstants::Red);
 
-    QChart *chart = new QChart();
+    chart = new QChart();
     chart->setTitle(QString("%1 \"%2\"").arg(code).arg(name));
     chart->addSeries(pwr_cool);
     chart->addSeries(pwr_heat);
@@ -114,16 +119,19 @@
     pwr_cool->attachAxis(axisYR);
     pwr_heat->attachAxis(axisYR);
 
-
+    connect(pv_air, &QSplineSeries::hovered, this, &ChartFermenter::tooltip);
+    connect(pv_beer, &QSplineSeries::hovered, this, &ChartFermenter::tooltip);
+    connect(pv_chiller, &QSplineSeries::hovered, this, &ChartFermenter::tooltip);
 
-    QChartView *chartView = new QChartView(chart);
+    chartView = new QChartView(chart);
     chartView->setRenderHint(QPainter::Antialiasing);
-    dialog->setLayout(new QVBoxLayout);
+    dialog->setLayout(new QHBoxLayout);
     dialog->layout()->addWidget(chartView);
     dialog->layout()->addWidget(buttonBox);
 
     QObject::connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
     QObject::connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
+    QObject::connect(saveButton, SIGNAL(clicked()), this, SLOT(savePNG()));
 
     dialog->setModal(true);
     dialog->exec();
@@ -132,3 +140,44 @@
 
 ChartFermenter::~ChartFermenter() {}
 
+
+void ChartFermenter::savePNG()
+{
+    QString path = QFileDialog::getSaveFileName(this, tr("Save Image"), QDir::homePath() + "/fermenter.png", tr("Image (*.png)"));
+    if (path.isEmpty()) {
+	QMessageBox::warning(this, tr("Save File"), tr("No image file selected."));
+	return;
+    }
+
+    QImage img((chartView->size()), QImage::Format_ARGB32);
+    QPainter painter;
+    painter.begin(&img);
+    chartView->render(&painter);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.end();
+    img.save(path);
+}
+
+
+void ChartFermenter::tooltip(QPointF point, bool state)
+{
+    QAbstractSeries *series = qobject_cast<QAbstractSeries *>(sender());
+
+    if (t_tooltip == 0)
+	t_tooltip = new Callout(chart, series);
+
+    if (state) {
+	QDateTime timeis = QDateTime::fromMSecsSinceEpoch(point.x());
+	//qDebug() << "tooltip" << QString("%1 %2°C").arg( timeis.toString("dd-MM-yyyy hh:mm") ).arg(point.y(), 2, 'f', 1);
+
+	t_tooltip->setSeries(series);
+	t_tooltip->setText(QString("%1\n%2 %3°C").arg(timeis.toString("dd-MM-yyyy hh:mm")).arg(series->name()).arg(point.y(), 2, 'f', 1));
+	t_tooltip->setAnchor(point);
+	t_tooltip->setZValue(11);
+	t_tooltip->updateGeometry();
+	t_tooltip->show();
+    } else {
+	t_tooltip->hide();
+    }
+}
+
--- a/src/ChartFermenter.h	Tue Jul 26 11:15:37 2022 +0200
+++ b/src/ChartFermenter.h	Tue Jul 26 14:26:50 2022 +0200
@@ -1,9 +1,12 @@
 #ifndef _CHARTFERMENTER_H
 #define _CHARTFERMENTER_H
 
+#include "MainWindow.h"
+
 #include <QDialog>
 #include <QDialogButtonBox>
 
+class Callout;
 
 namespace Ui {
 class ChartFermenter;
@@ -13,10 +16,20 @@
 {
     Q_OBJECT
 
+private slots:
+    void savePNG();
+
+public slots:
+    void tooltip(QPointF point, bool state);
+
 public:
     explicit ChartFermenter(QString code, QString name, QWidget *parent = 0);
     ~ChartFermenter();
 
+private:
+    QChartView *chartView;
+    QChart *chart;
+    Callout *t_tooltip = 0;
 };
 
 #endif
--- a/src/ChartiSpindel.cpp	Tue Jul 26 11:15:37 2022 +0200
+++ b/src/ChartiSpindel.cpp	Tue Jul 26 14:26:50 2022 +0200
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include "ChartiSpindel.h"
+#include "callout.h"
 #include "MainWindow.h"
 
 
@@ -31,17 +32,21 @@
     dialog->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint);
     dialog->resize(1024, 600);
 
+    QPushButton *saveButton = new QPushButton(tr("Save"));
+    saveButton->setAutoDefault(false);
+    QIcon icon1;
+    icon1.addFile(QString::fromUtf8(":icons/silk/disk.png"), QSize(), QIcon::Normal, QIcon::Off);
+    saveButton->setIcon(icon1);
+
     QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog);
     buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
-    buttonBox->setGeometry(QRect(40, 565, 944, 36));
-    buttonBox->setLayoutDirection(Qt::LeftToRight);
-    buttonBox->setOrientation(Qt::Horizontal);
+    buttonBox->setOrientation(Qt::Vertical);
     buttonBox->setStandardButtons(QDialogButtonBox::Ok);
-    buttonBox->setCenterButtons(true);
+    buttonBox->addButton(saveButton,QDialogButtonBox::ActionRole);
 
-    QSplineSeries *temperature = new QSplineSeries();
-    QSplineSeries *density = new QSplineSeries();
-    QSplineSeries *battery = new QSplineSeries();
+    temperature = new QSplineSeries();
+    density = new QSplineSeries();
+    battery = new QSplineSeries();
 
     query.prepare("SELECT * FROM log_ispindel WHERE code=:code ORDER BY datetime");
     query.bindValue(":code", code);
@@ -53,7 +58,7 @@
         battery ->append(timestamp, query.value("battery").toDouble());
     }
 
-    temperature->setName(tr("Temp °C"));
+    temperature->setName(tr("Temperature"));
     temperature->setColor(QColorConstants::Svg::red);
     density->setName(tr("SG"));
     QPen pen(QColorConstants::Svg::navy);
@@ -62,7 +67,7 @@
     battery->setName(tr("Battery"));
     battery->setColor(QColorConstants::Svg::limegreen);
 
-    QChart *chart = new QChart();
+    chart = new QChart();
     chart->setTitle(QString("%1 \"%2\"").arg(code).arg(name));
     chart->addSeries(battery);
     chart->addSeries(temperature);
@@ -102,14 +107,19 @@
     chart->addAxis(axisYB, Qt::AlignRight);
     battery->attachAxis(axisYB);
 
-    QChartView *chartView = new QChartView(chart);
+    connect(temperature, &QSplineSeries::hovered, this, &ChartiSpindel::tooltip);
+    connect(density, &QSplineSeries::hovered, this, &ChartiSpindel::tooltip);
+    connect(battery, &QSplineSeries::hovered, this, &ChartiSpindel::tooltip);
+
+    chartView = new QChartView(chart);
     chartView->setRenderHint(QPainter::Antialiasing);
-    dialog->setLayout(new QVBoxLayout);
+    dialog->setLayout(new QHBoxLayout);
     dialog->layout()->addWidget(chartView);
     dialog->layout()->addWidget(buttonBox);
 
     QObject::connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
     QObject::connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
+    QObject::connect(saveButton, SIGNAL(clicked()), this, SLOT(savePNG()));
 
     dialog->setModal(true);
     dialog->exec();
@@ -118,3 +128,47 @@
 
 ChartiSpindel::~ChartiSpindel() {}
 
+
+void ChartiSpindel::savePNG()
+{
+    QString path = QFileDialog::getSaveFileName(this, tr("Save Image"), QDir::homePath() + "/ispindel.png", tr("Image (*.png)"));
+    if (path.isEmpty()) {
+	QMessageBox::warning(this, tr("Save File"), tr("No image file selected."));
+	return;
+    }
+
+    QImage img((chartView->size()), QImage::Format_ARGB32);
+    QPainter painter;
+    painter.begin(&img);
+    chartView->render(&painter);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.end();
+    img.save(path);
+}
+
+
+void ChartiSpindel::tooltip(QPointF point, bool state)
+{
+    QAbstractSeries *series = qobject_cast<QAbstractSeries *>(sender());
+
+    if (t_tooltip == 0)
+	t_tooltip = new Callout(chart, series);
+
+    if (state) {
+	QDateTime timeis = QDateTime::fromMSecsSinceEpoch(point.x());
+	t_tooltip->setSeries(series);
+	if (series == temperature)
+	    t_tooltip->setText(QString("%1\nTemperature %2°C").arg(timeis.toString("dd-MM-yyyy hh:mm")).arg(point.y(), 2, 'f', 1));
+	else if (series == density)
+	    t_tooltip->setText(QString("%1\nDensity %2 SG").arg(timeis.toString("dd-MM-yyyy hh:mm")).arg(point.y(), 5, 'f', 4));
+	else if (series == battery)
+	    t_tooltip->setText(QString("%1\nBattery %2 volt").arg(timeis.toString("dd-MM-yyyy hh:mm")).arg(point.y(), 3, 'f', 2));
+	t_tooltip->setAnchor(point);
+	t_tooltip->setZValue(11);
+	t_tooltip->updateGeometry();
+	t_tooltip->show();
+    } else {
+	t_tooltip->hide();
+    }
+}
+
--- a/src/ChartiSpindel.h	Tue Jul 26 11:15:37 2022 +0200
+++ b/src/ChartiSpindel.h	Tue Jul 26 14:26:50 2022 +0200
@@ -1,9 +1,12 @@
 #ifndef _CHARTISPINDEL_H
 #define _CHARTISPINDEL_H
 
+#include "MainWindow.h"
+
 #include <QDialog>
 #include <QDialogButtonBox>
 
+class Callout;
 
 namespace Ui {
 class ChartiSpindel;
@@ -13,10 +16,21 @@
 {
     Q_OBJECT
 
+private slots:
+    void savePNG();
+
+public slots:
+    void tooltip(QPointF point, bool state);
+
 public:
     explicit ChartiSpindel(QString code, QString name, QWidget *parent = 0);
     ~ChartiSpindel();
 
+private:
+    QChartView *chartView;
+    QChart *chart;
+    Callout *t_tooltip = 0;
+    QSplineSeries *temperature, *density, *battery;
 };
 
 #endif
--- a/src/EditProduct.cpp	Tue Jul 26 11:15:37 2022 +0200
+++ b/src/EditProduct.cpp	Tue Jul 26 14:26:50 2022 +0200
@@ -15,6 +15,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include "MainWindow.h"
+#include "callout.h"
 #include "EditProduct.h"
 #include "PrinterDialog.h"
 #include "ChartCarbonate.h"
--- a/src/EditProduct.h	Tue Jul 26 11:15:37 2022 +0200
+++ b/src/EditProduct.h	Tue Jul 26 14:26:50 2022 +0200
@@ -1,6 +1,8 @@
 #ifndef _EDITPRODUCT_H
 #define _EDITPRODUCT_H
 
+#include "MainWindow.h"
+
 #include <QDialog>
 #include <QStringList>
 #include <QJsonDocument>
@@ -19,6 +21,8 @@
 
 #include "global.h"
 
+class Callout;
+
 struct StepResult {
     double	svol;
     double	irate;
@@ -42,6 +46,9 @@
     explicit EditProduct(int id, QWidget *parent = 0);
     ~EditProduct();
 
+public slots:
+    void tooltip(QPointF point, bool state);
+
 private slots:
     void on_saveButton_clicked();
     void on_quitButton_clicked();
@@ -190,6 +197,7 @@
     void brew_trubloss_changed(double val);
     void brew_topupwater_changed(double val);
     void brew_log_button();
+    void savePNG();
     void brix_changed(double val);
     void primary_start_changed(double val);
     void primary_peak_changed(double val);
@@ -273,6 +281,9 @@
     QLabel *htimeLabel, *mtimeLabel, *mamountLabel, *yamountLabel, *ivolLabel, *itmpLabel;
     QTableWidget *splitTable;
     QPushButton *split_addButton, *split_delButton;
+    QChart *chart;
+    QChartView *chartView;
+    Callout *t_tooltip = 0;
 
     void to100Fermentables(int row);
     static bool ferment_sort_test(const Fermentables &D1, const Fermentables &D2);
--- a/src/EditProductTab9.cpp	Tue Jul 26 11:15:37 2022 +0200
+++ b/src/EditProductTab9.cpp	Tue Jul 26 14:26:50 2022 +0200
@@ -463,13 +463,18 @@
 
     QDialog* dialog = new QDialog(this);
     dialog->resize(1024, 600);
+
+    QPushButton *saveButton = new QPushButton(tr("Save"));
+    saveButton->setAutoDefault(false);
+    QIcon icon1;
+    icon1.addFile(QString::fromUtf8(":icons/silk/disk.png"), QSize(), QIcon::Normal, QIcon::Off);
+    saveButton->setIcon(icon1);
+
     QDialogButtonBox *buttonBox = new QDialogButtonBox(dialog);
     buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
-    buttonBox->setGeometry(QRect(40, 565, 944, 36));
-    buttonBox->setLayoutDirection(Qt::LeftToRight);
-    buttonBox->setOrientation(Qt::Horizontal);
+    buttonBox->setOrientation(Qt::Vertical);
     buttonBox->setStandardButtons(QDialogButtonBox::Ok);
-    buttonBox->setCenterButtons(true);
+    buttonBox->addButton(saveButton,QDialogButtonBox::ActionRole);
 
     QLineSeries *pv_mlt = new QLineSeries();
     pv_mlt->setName("MLT");
@@ -501,7 +506,7 @@
     pwm_mlt->setName("MLT pwr");
     pwm_mlt->setOpacity(0.25);
 
-    QChart *chart = new QChart();
+    chart = new QChart();
     chart->setTitle(QString("%1 \"%2\"").arg(product->code).arg(product->name));
     chart->addSeries(pwm_mlt);	// Order is important, first drawn is lowest layer.
     chart->addSeries(sp_mlt);
@@ -531,15 +536,59 @@
     sp_mlt->attachAxis(axisY);
     pv_hlt->attachAxis(axisY);
 
-    QChartView *chartView = new QChartView(chart);
+    connect(pv_mlt, &QLineSeries::hovered, this, &EditProduct::tooltip);
+    connect(pv_hlt, &QLineSeries::hovered, this, &EditProduct::tooltip);
+
+    chartView = new QChartView(chart);
     chartView->setRenderHint(QPainter::Antialiasing);
-    dialog->setLayout(new QVBoxLayout);
+    dialog->setLayout(new QHBoxLayout);
     dialog->layout()->addWidget(chartView);
     dialog->layout()->addWidget(buttonBox);
 
     connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
+    connect(saveButton, SIGNAL(clicked()), this, SLOT(savePNG()));
+
     dialog->setModal(true);
     dialog->exec();
 }
 
 
+void EditProduct::savePNG()
+{
+    QString path = QFileDialog::getSaveFileName(this, tr("Save Image"), QDir::homePath() + "/brewday.png", tr("Image (*.png)"));
+    if (path.isEmpty()) {
+	QMessageBox::warning(this, tr("Save File"), tr("No image file selected."));
+	return;
+    }
+
+    QImage img((chartView->size()), QImage::Format_ARGB32);
+    QPainter painter;
+    painter.begin(&img);
+    chartView->render(&painter);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.end();
+    img.save(path);
+}
+
+
+void EditProduct::tooltip(QPointF point, bool state)
+{
+    QAbstractSeries *series = qobject_cast<QAbstractSeries *>(sender());
+
+    if (t_tooltip == 0)
+	t_tooltip = new Callout(chart, series);
+
+    if (state) {
+	QDateTime timeis = QDateTime::fromMSecsSinceEpoch(point.x());
+	t_tooltip->setSeries(series);
+	t_tooltip->setText(QString("%1\n%2 %3°C").arg(timeis.toString("dd-MM-yyyy hh:mm")).arg(series->name()).arg(point.y(), 2, 'f', 1));
+	t_tooltip->setAnchor(point);
+	t_tooltip->setZValue(11);
+	t_tooltip->updateGeometry();
+	t_tooltip->show();
+    } else {
+	t_tooltip->hide();
+    }
+}
+
+

mercurial