2018-12-19 00:13:18 +08:00
|
|
|
/*
|
2022-07-19 19:40:43 +08:00
|
|
|
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
|
2018-12-19 00:13:18 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This software is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
2019-02-08 00:24:46 +08:00
|
|
|
the Free Software Foundation, either version 2.1 of the License, or
|
2018-12-19 00:13:18 +08:00
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Lesser General Public License (LGPL) for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-06-20 22:06:31 +08:00
|
|
|
#include "jkqtplotter/graphs/jkqtppeakstream.h"
|
2018-12-19 00:13:18 +08:00
|
|
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <QDebug>
|
|
|
|
#include <iostream>
|
2019-05-30 04:40:02 +08:00
|
|
|
#include "jkqtplotter/jkqtptools.h"
|
2018-12-19 00:13:18 +08:00
|
|
|
#include "jkqtplotter/jkqtpbaseelements.h"
|
|
|
|
#include "jkqtplotter/jkqtplotter.h"
|
2019-05-30 04:40:02 +08:00
|
|
|
#include "jkqtcommon/jkqtpdrawingtools.h"
|
2018-12-19 00:13:18 +08:00
|
|
|
#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-01-20 17:49:29 +08:00
|
|
|
JKQTPPeakStreamGraph::JKQTPPeakStreamGraph(JKQTBasePlotter *parent):
|
|
|
|
JKQTPSingleColumnGraph(parent)
|
2018-12-19 00:13:18 +08:00
|
|
|
{
|
|
|
|
baseline=0;
|
|
|
|
yPeaks=true;
|
|
|
|
peakHeight=1;
|
|
|
|
drawBaseline=true;
|
2020-09-26 21:58:58 +08:00
|
|
|
initLineStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Default);
|
2018-12-19 00:13:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-01-20 23:15:10 +08:00
|
|
|
JKQTPPeakStreamGraph::JKQTPPeakStreamGraph(JKQTPlotter *parent):
|
2019-02-08 00:24:46 +08:00
|
|
|
JKQTPPeakStreamGraph(parent->getPlotter())
|
2018-12-19 00:13:18 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool JKQTPPeakStreamGraph::getXMinMax(double &minx, double &maxx, double &smallestGreaterZero)
|
|
|
|
{
|
|
|
|
if (yPeaks) {
|
|
|
|
return getDataMinMax(dataColumn, minx, maxx, smallestGreaterZero);
|
|
|
|
} else {
|
|
|
|
minx=qMin(baseline, baseline+peakHeight);
|
|
|
|
maxx=qMax(baseline, baseline+peakHeight);
|
|
|
|
return true;
|
|
|
|
//smallestGreaterZero=qMax(double(0.0), qMin(baseline, baseline+peakHeight));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool JKQTPPeakStreamGraph::getYMinMax(double &miny, double &maxy, double &smallestGreaterZero)
|
|
|
|
{
|
|
|
|
if (!yPeaks) {
|
|
|
|
return getDataMinMax(dataColumn, miny, maxy, smallestGreaterZero);
|
|
|
|
} else {
|
|
|
|
miny=qMin(baseline, baseline+peakHeight);
|
|
|
|
maxy=qMax(baseline, baseline+peakHeight);
|
|
|
|
return true;
|
|
|
|
//smallestGreaterZero=qMax(double(0.0), qMin(baseline, baseline+peakHeight));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void JKQTPPeakStreamGraph::draw(JKQTPEnhancedPainter &painter)
|
|
|
|
{
|
|
|
|
#ifdef JKQTBP_AUTOTIMER
|
|
|
|
JKQTPAutoOutputTimer jkaaot("JKQTPPeakStreamGraph::draw");
|
|
|
|
#endif
|
|
|
|
if (parent==nullptr) return;
|
2019-01-20 17:49:29 +08:00
|
|
|
JKQTPDatastore* datastore=parent->getDatastore();
|
2018-12-19 00:13:18 +08:00
|
|
|
if (datastore==nullptr) return;
|
|
|
|
if (dataColumn<0) return;
|
|
|
|
|
|
|
|
drawErrorsBefore(painter);
|
2019-02-08 00:24:46 +08:00
|
|
|
{
|
|
|
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
|
|
|
|
2019-04-22 19:27:50 +08:00
|
|
|
QPen p=getLinePen(painter, parent);
|
2019-02-08 00:24:46 +08:00
|
|
|
p.setCapStyle(Qt::FlatCap);
|
|
|
|
|
2019-05-13 04:22:48 +08:00
|
|
|
int imax=static_cast<int>(datastore->getRows(static_cast<size_t>(dataColumn)));
|
2019-02-08 00:24:46 +08:00
|
|
|
int imin=0;
|
|
|
|
if (imax<imin) {
|
|
|
|
int h=imin;
|
|
|
|
imin=imax;
|
|
|
|
imax=h;
|
|
|
|
}
|
|
|
|
if (imin<0) imin=0;
|
|
|
|
if (imax<0) imax=0;
|
2018-12-19 00:13:18 +08:00
|
|
|
|
2019-02-08 00:24:46 +08:00
|
|
|
QVector<QLineF> lines;
|
2018-12-19 00:13:18 +08:00
|
|
|
|
2019-02-08 00:24:46 +08:00
|
|
|
if (yPeaks) {
|
|
|
|
if (drawBaseline) {
|
|
|
|
lines<<QLineF(transform(parent->getXMin(), baseline), transform(parent->getXMax(), baseline));
|
2018-12-19 00:13:18 +08:00
|
|
|
}
|
2019-02-08 00:24:46 +08:00
|
|
|
intSortData();
|
|
|
|
for (int iii=imin; iii<imax; iii++) {
|
|
|
|
int i=qBound<int>(imin, getDataIndex(static_cast<int>(iii)), imax);
|
2019-04-22 19:27:50 +08:00
|
|
|
const double xv=datastore->get(dataColumn,static_cast<size_t>(i));
|
2019-02-08 00:24:46 +08:00
|
|
|
if (JKQTPIsOKFloat(xv)) {
|
|
|
|
lines<<QLineF(transform(xv, baseline), transform(xv, baseline+peakHeight));
|
2019-05-06 01:31:20 +08:00
|
|
|
addHitTestData(xv, (baseline+peakHeight)/2.0,iii, datastore);
|
2019-02-08 00:24:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (drawBaseline) {
|
|
|
|
lines<<QLineF(transform(baseline, parent->getYMin()), transform(baseline, parent->getYMax()));
|
|
|
|
}
|
|
|
|
intSortData();
|
|
|
|
for (int iii=imin; iii<imax; iii++) {
|
|
|
|
int i=qBound<int>(imin, getDataIndex(iii), imax);
|
2019-04-22 19:27:50 +08:00
|
|
|
const double yv=datastore->get(dataColumn,static_cast<size_t>(i));
|
2019-02-08 00:24:46 +08:00
|
|
|
if (JKQTPIsOKFloat(yv)) {
|
|
|
|
lines<<QLineF(transform(baseline, yv), transform(baseline+peakHeight, yv));
|
2019-05-06 01:31:20 +08:00
|
|
|
addHitTestData((baseline+peakHeight)/2.0, yv,iii, datastore);
|
2019-02-08 00:24:46 +08:00
|
|
|
}
|
2018-12-19 00:13:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 00:24:46 +08:00
|
|
|
painter.setPen(p);
|
|
|
|
if (lines.size()>0) painter.drawLines(lines);
|
2018-12-19 00:13:18 +08:00
|
|
|
|
|
|
|
|
2019-02-08 00:24:46 +08:00
|
|
|
}
|
2018-12-19 00:13:18 +08:00
|
|
|
|
|
|
|
drawErrorsAfter(painter);
|
|
|
|
}
|
|
|
|
|
|
|
|
void JKQTPPeakStreamGraph::drawKeyMarker(JKQTPEnhancedPainter &painter, QRectF &rect)
|
|
|
|
{
|
2019-02-08 00:24:46 +08:00
|
|
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
2019-04-22 19:27:50 +08:00
|
|
|
QPen p=getLinePen(painter, parent);
|
2018-12-19 00:13:18 +08:00
|
|
|
painter.setPen(p);
|
|
|
|
if (yPeaks) {
|
2019-05-13 04:22:48 +08:00
|
|
|
p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,qMin(parent->pt2px(painter, p.widthF()), rect.width()/10.0)));
|
2018-12-19 00:13:18 +08:00
|
|
|
if (drawBaseline) {
|
|
|
|
if (peakHeight>=0) painter.drawLine(rect.bottomLeft(), rect.bottomRight());
|
|
|
|
else painter.drawLine(rect.topLeft(), rect.topRight());
|
|
|
|
}
|
|
|
|
painter.drawLine(QPointF(rect.left()+rect.width()*0.1, rect.top()),QPointF( rect.left()+rect.width()*0.1, rect.bottom()));
|
|
|
|
painter.drawLine(QPointF(rect.left()+rect.width()*0.55, rect.top()), QPointF(rect.left()+rect.width()*0.55, rect.bottom()));
|
|
|
|
painter.drawLine(QPointF(rect.left()+rect.width()*0.75, rect.top()), QPointF(rect.left()+rect.width()*0.75, rect.bottom()));
|
|
|
|
painter.drawLine(QPointF(rect.left()+rect.width()*0.9, rect.top()), QPointF(rect.left()+rect.width()*0.9, rect.bottom()));
|
|
|
|
} else {
|
2019-05-13 04:22:48 +08:00
|
|
|
p.setWidthF(qMax(JKQTPlotterDrawingTools::ABS_MIN_LINEWIDTH,qMin(parent->pt2px(painter, p.widthF()), rect.height()/15.0)));
|
2018-12-19 00:13:18 +08:00
|
|
|
if (drawBaseline) {
|
|
|
|
if (peakHeight>=0) painter.drawLine(rect.bottomLeft(), rect.topLeft());
|
|
|
|
else painter.drawLine(rect.bottomRight(), rect.topRight());
|
|
|
|
}
|
|
|
|
painter.drawLine(QPointF(rect.left(), rect.top()+rect.height()*0.1), QPointF(rect.right(), rect.top()+rect.height()*0.1));
|
|
|
|
painter.drawLine(QPointF(rect.left(), rect.top()+rect.height()*0.55), QPointF(rect.right(), rect.top()+rect.height()*0.55));
|
|
|
|
painter.drawLine(QPointF(rect.left(), rect.top()+rect.height()*0.75), QPointF(rect.right(), rect.top()+rect.height()*0.75));
|
|
|
|
painter.drawLine(QPointF(rect.left(), rect.top()+rect.height()*0.9), QPointF(rect.right(), rect.top()+rect.height()*0.9));
|
|
|
|
}
|
|
|
|
|
2019-02-08 00:24:46 +08:00
|
|
|
|
2018-12-19 00:13:18 +08:00
|
|
|
}
|
|
|
|
|
2019-04-22 19:27:50 +08:00
|
|
|
QColor JKQTPPeakStreamGraph::getKeyLabelColor() const
|
|
|
|
{
|
|
|
|
return getLineColor();
|
|
|
|
}
|
|
|
|
|
|
|
|
void JKQTPPeakStreamGraph::setColor(QColor col)
|
|
|
|
{
|
|
|
|
setLineColor(col);
|
|
|
|
}
|
|
|
|
|
|
|
|
void JKQTPPeakStreamGraph::setBaseline(double __value)
|
|
|
|
{
|
|
|
|
this->baseline = __value;
|
|
|
|
}
|
|
|
|
|
|
|
|
double JKQTPPeakStreamGraph::getBaseline() const
|
|
|
|
{
|
|
|
|
return this->baseline;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JKQTPPeakStreamGraph::setPeakHeight(double __value)
|
|
|
|
{
|
|
|
|
this->peakHeight = __value;
|
|
|
|
}
|
|
|
|
|
|
|
|
double JKQTPPeakStreamGraph::getPeakHeight() const
|
|
|
|
{
|
|
|
|
return this->peakHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JKQTPPeakStreamGraph::setYPeaks(bool __value)
|
|
|
|
{
|
|
|
|
this->yPeaks = __value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool JKQTPPeakStreamGraph::getYPeaks() const
|
|
|
|
{
|
|
|
|
return this->yPeaks;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JKQTPPeakStreamGraph::setDrawBaseline(bool __value)
|
|
|
|
{
|
|
|
|
this->drawBaseline = __value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool JKQTPPeakStreamGraph::getDrawBaseline() const
|
|
|
|
{
|
|
|
|
return this->drawBaseline;
|
|
|
|
}
|
|
|
|
|
2018-12-19 00:13:18 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|