diff --git a/.gitignore b/.gitignore
index 22bc77c063..3bc02cd7d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -101,3 +101,25 @@ Sicherungskopie_*
/out
*.synctex.gz
*.bak
+/doc/images/JKQTPImpulsesHorizontalErrorGraphBaseline.png
+/doc/images/JKQTPImpulsesHorizontalErrorGraphBaseline_small.png
+/doc/images/JKQTPImpulsesHorizontalErrorGraphNoBaseline.png
+/doc/images/JKQTPImpulsesHorizontalErrorGraphNoBaseline_small.png
+/doc/images/JKQTPImpulsesHorizontalGraphBaseline_small.png
+/doc/images/JKQTPImpulsesHorizontalGraphNoBaseline_small.png
+/doc/images/JKQTPImpulsesVerticalErrorGraphBaseline.png
+/doc/images/JKQTPImpulsesVerticalErrorGraphBaseline_small.png
+/doc/images/JKQTPImpulsesVerticalErrorGraphNoBaseline.png
+/doc/images/JKQTPImpulsesVerticalErrorGraphNoBaseline_small.png
+/doc/images/JKQTPImpulsesVerticalGraphBaseline_small.png
+/doc/images/JKQTPImpulsesVerticalGraphNoBaseline_small.png
+/doc/images/JKQTPImpulsesVerticalGraph_SymbolsBaseline.png
+/doc/images/JKQTPImpulsesVerticalGraph_SymbolsBaseline_small.png
+/doc/images/JKQTPImpulsesVerticalGraph_SymbolsNoBaseline.png
+/doc/images/JKQTPImpulsesVerticalGraph_SymbolsNoBaseline_small.png
+/doc/images/JKQTPBarHorizontalGraphBaseline.png
+/doc/images/JKQTPBarHorizontalGraphBaseline_small.png
+/doc/images/JKQTPBarHorizontalGraphNoBaseline.png
+/doc/images/JKQTPBarHorizontalGraphNoBaseline_small.png
+/doc/images/JKQTPBarVerticalGraphBaseline_small.png
+/doc/images/JKQTPBarVerticalGraphNoBaseline_small.png
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 06e16c30f5..8a3edc05bf 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -193,7 +193,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
stackedbars/JKQTPbarVerticalGraphStacked,JKQTPbarHorizontalGraphStacked/--smallscreenshotplot
scatter/JKQTPXYScatterGraph,JKQTPXYScatterErrorGraph/--smallscreenshotplot
simpletest/JKQTPXYLineGraph/--smallscreenshotplot
- barchart/JKQTPBarVerticalGraph,JKQTPBarHorizontalGraph/--smallscreenshotplot
+ barchart/JKQTPBarVerticalGraph,JKQTPBarHorizontalGraph,JKQTPBarVerticalGraphNoBaseline,JKQTPBarHorizontalGraphNoBaseline,JKQTPBarVerticalGraphBaseline,JKQTPBarHorizontalGraphBaseline/--iteratefunctorsteps--smallscreenshotplot
barchart_twocolor/JKQTPBarVerticalGraphTwoColorFilling,JKQTPBarHorizontalGraphTwoColorFilling/--smallscreenshotplot
barchart_errorbars/JKQTPBarVerticalErrorGraph,JKQTPBarHorizontalErrorGraph/--smallscreenshotplot
barchart_functorfill/JKQTPBarVerticalGraphFunctorFilling,JKQTPBarHorizontalGraphFunctorFilling/--smallscreenshotplot
@@ -204,7 +204,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
filledgraphs_errors/JKQTPFilledCurveXErrorGraph,JKQTPFilledCurveYErrorGraph/--smallscreenshotplot
evalcurve/JKQTPXYFunctionLineGraph/--smallscreenshotplot
geo_coordinateaxis0/JKQTPCoordinateAxisStyleDrawMode0
- impulsesplot/JKQTPImpulsesVerticalGraph,JKQTPImpulsesVerticalGraph_Symbols,JKQTPImpulsesHorizontalGraph,JKQTPImpulsesVerticalErrorGraph,JKQTPImpulsesHorizontalErrorGraph/--smallscreenshotplot
+ impulsesplot/JKQTPImpulsesVerticalGraph,JKQTPImpulsesVerticalGraph_Symbols,JKQTPImpulsesHorizontalGraph,JKQTPImpulsesVerticalErrorGraph,JKQTPImpulsesHorizontalErrorGraph,JKQTPImpulsesVerticalGraphNoBaseline,JKQTPImpulsesVerticalGraph_SymbolsNoBaseline,JKQTPImpulsesHorizontalGraphNoBaseline,JKQTPImpulsesVerticalErrorGraphNoBaseline,JKQTPImpulsesHorizontalErrorGraphNoBaseline,JKQTPImpulsesVerticalGraphBaseline,JKQTPImpulsesVerticalGraph_SymbolsBaseline,JKQTPImpulsesHorizontalGraphBaseline,JKQTPImpulsesVerticalErrorGraphBaseline,JKQTPImpulsesHorizontalErrorGraphBaseline/--iteratefunctorsteps--smallscreenshotplot
symbols_and_errors/JKQTPXYLineErrorGraph_JKQTPErrorBars,JKQTPXYLineErrorGraph_JKQTPErrorLines,JKQTPXYLineErrorGraph_JKQTPErrorPolygons/--iteratefunctorsteps--iteratefunctorsteps_suppressinitial--smallscreenshotplot
boxplot/JKQTPBoxplotVerticalGraph,JKQTPBoxplotHorizontalGraph/--iteratefunctorsteps--iteratefunctorsteps_suppressinitial--smallscreenshotplot
)
diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox
index 1f221b70a6..19560a6615 100644
--- a/doc/dox/whatsnew.dox
+++ b/doc/dox/whatsnew.dox
@@ -65,6 +65,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
NEW: barcharts may have rounded corners now, via JKQTPBarGraphBase::setRectRadius()
NEW: barcharts can be colored by a user-specified functor
NEW: you can provide a custom draw functor to barcharts to completely customize their look
+ NEW: barcharts and impulse graphs may now draw their baseline as stylable line (default: off)
JKQTMathText:
diff --git a/doc/images/JKQTPBarVerticalGraphBaseline.png b/doc/images/JKQTPBarVerticalGraphBaseline.png
new file mode 100644
index 0000000000..31179f2cd7
Binary files /dev/null and b/doc/images/JKQTPBarVerticalGraphBaseline.png differ
diff --git a/doc/images/JKQTPBarVerticalGraphNoBaseline.png b/doc/images/JKQTPBarVerticalGraphNoBaseline.png
new file mode 100644
index 0000000000..cfecbc7f50
Binary files /dev/null and b/doc/images/JKQTPBarVerticalGraphNoBaseline.png differ
diff --git a/doc/images/JKQTPImpulsesHorizontalGraphBaseline.png b/doc/images/JKQTPImpulsesHorizontalGraphBaseline.png
new file mode 100644
index 0000000000..4dbcb204ef
Binary files /dev/null and b/doc/images/JKQTPImpulsesHorizontalGraphBaseline.png differ
diff --git a/doc/images/JKQTPImpulsesHorizontalGraphNoBaseline.png b/doc/images/JKQTPImpulsesHorizontalGraphNoBaseline.png
new file mode 100644
index 0000000000..c1d3d7dcee
Binary files /dev/null and b/doc/images/JKQTPImpulsesHorizontalGraphNoBaseline.png differ
diff --git a/doc/images/JKQTPImpulsesVerticalGraphBaseline.png b/doc/images/JKQTPImpulsesVerticalGraphBaseline.png
new file mode 100644
index 0000000000..c8cd9f0065
Binary files /dev/null and b/doc/images/JKQTPImpulsesVerticalGraphBaseline.png differ
diff --git a/doc/images/JKQTPImpulsesVerticalGraphNoBaseline.png b/doc/images/JKQTPImpulsesVerticalGraphNoBaseline.png
new file mode 100644
index 0000000000..3a79e01d3d
Binary files /dev/null and b/doc/images/JKQTPImpulsesVerticalGraphNoBaseline.png differ
diff --git a/examples/barchart/barchart.cpp b/examples/barchart/barchart.cpp
index c7af00d5f2..c85a4c864b 100644
--- a/examples/barchart/barchart.cpp
+++ b/examples/barchart/barchart.cpp
@@ -15,14 +15,13 @@
template
-void doExample(const QString& title)
+std::vector doExample(JKQTPlotter& plot, const QString& title)
{
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
- JKQTPlotter* plot=new JKQTPlotter();
- plot->getPlotter()->setUseAntiAliasingForGraphs(true); // nicer (but slower) plotting
- plot->getPlotter()->setUseAntiAliasingForSystem(true); // nicer (but slower) plotting
- plot->getPlotter()->setUseAntiAliasingForText(true); // nicer (but slower) text rendering
- JKQTPDatastore* ds=plot->getDatastore();
+ plot.getPlotter()->setUseAntiAliasingForGraphs(true); // nicer (but slower) plotting
+ plot.getPlotter()->setUseAntiAliasingForSystem(true); // nicer (but slower) plotting
+ plot.getPlotter()->setUseAntiAliasingForText(true); // nicer (but slower) text rendering
+ JKQTPDatastore* ds=plot.getDatastore();
// 2. now we create data for three simple barchart
QString L[Ndata]={ "cat. A", "cat. C", "cat. B", "cat. D", "other"}; // unsorted category axis
@@ -44,24 +43,24 @@ void doExample(const QString& title)
size_t columnY3=ds->addCopiedColumn(Y3, Ndata, "y3");
// 4. create graphs in the plot, which plots the dataset X/Y1, X/Y2 and X/Y3:
- TCHART* graph1=new TCHART(plot);
+ TCHART* graph1=new TCHART(&plot);
graph1->setBarPositionColumn(columnX);
graph1->setBarHeightColumn(columnY1);
graph1->setTitle(QObject::tr("dataset 1"));
- TCHART* graph2=new TCHART(plot);
+ TCHART* graph2=new TCHART(&plot);
graph2->setBarPositionColumn(columnX);
graph2->setBarHeightColumn(columnY2);
graph2->setTitle(QObject::tr("dataset 2"));
- TCHART* graph3=new TCHART(plot);
+ TCHART* graph3=new TCHART(&plot);
graph3->setBarPositionColumn(columnX);
graph3->setBarHeightColumn(columnY3);
graph3->setTitle(QObject::tr("dataset 3"));
// 5. add the graphs to the plot, so it is actually displayed
- plot->addGraph(graph1);
- plot->addGraph(graph2);
- plot->addGraph(graph3);
+ plot.addGraph(graph1);
+ plot.addGraph(graph2);
+ plot.addGraph(graph3);
// 6. now we set the graphs, so they are plotted side-by-side
// This function searches all JKQTPBarHorizontalGraph in the current
@@ -73,16 +72,16 @@ void doExample(const QString& title)
// 7. data is grouped into 5 numbere groups (1..5), but we also have string
// labels for these groups (stored in L). In order to display these labels,
// we have to tell the x-Axis to use these special labels:
- plot->getXAxis()->addAxisTickLabels(X, L, Ndata);
+ plot.getXAxis()->addAxisTickLabels(X, L, Ndata);
// also we can rotate the labels a bit (by 45 degree), so they fit better
- plot->getXAxis()->setTickLabelAngle(45);
- plot->getXAxis()->setTickLabelFontSize(12);
+ plot.getXAxis()->setTickLabelAngle(45);
+ plot.getXAxis()->setTickLabelFontSize(12);
} else {
// 7. data is grouped into 5 numbere groups (1..5), but we also have string
// labels for these groups (stored in L). In order to display these labels,
// we have to tell the x-Axis to use these special labels:
- plot->getYAxis()->addAxisTickLabels(X, L, Ndata);
- plot->getYAxis()->setTickLabelFontSize(12);
+ plot.getYAxis()->addAxisTickLabels(X, L, Ndata);
+ plot.getYAxis()->setTickLabelFontSize(12);
}
// 8. finally we move the plot key/legend to the outside, top-right
@@ -90,17 +89,19 @@ void doExample(const QString& title)
// NOTE: plot is a descendent of QWidget, which uses an internal object of
// type JKQTBasePlotter, which does the actual plotting.
// So many properties of the plot are only available in this internal
- // object, which you can access by plot->getPlotter().
- plot->getPlotter()->setKeyPosition(JKQTPKeyOutsideTopRight);
- plot->getPlotter()->setKeyLayout(JKQTPKeyLayoutOneRow);
+ // object, which you can access by plot.getPlotter().
+ plot.getPlotter()->setKeyPosition(JKQTPKeyOutsideTopRight);
+ plot.getPlotter()->setKeyLayout(JKQTPKeyLayoutOneRow);
// 9 autoscale the plot so the graph is contained
- plot->zoomToFit();
+ plot.zoomToFit();
// show plotter and make it a decent size
- plot->setWindowTitle(title);
- plot->show();
- plot->resize(600/plot->devicePixelRatioF(),550/plot->devicePixelRatioF());
+ plot.setWindowTitle(title);
+ plot.show();
+ plot.resize(600/plot.devicePixelRatioF(),550/plot.devicePixelRatioF());
+
+ return {graph1, graph2, graph3};
}
int main(int argc, char* argv[])
@@ -109,9 +110,35 @@ int main(int argc, char* argv[])
JKQTPAppSettingController highDPIController(argc,argv);
JKQTPExampleApplication app(argc, argv);
+ JKQTPlotter plotV;
+ auto gV=doExample(plotV, "1: JKQTPBarVerticalGraph");
+ JKQTPlotter plotH;
+ auto gH=doExample(plotH, "2: JKQTPBarHorizontalGraph");
- doExample("1: JKQTPBarVerticalGraph");
- doExample("2: JKQTPBarHorizontalGraph");
+ app.addExportStepFunctor([&](){
+ for (auto g: gV) {
+ g->setDrawBaseline(false);
+ }
+ for (auto g: gH) {
+ g->setDrawBaseline(false);
+ }
+ plotV.getXAxis()->setShowZeroAxis(false);
+ plotV.getYAxis()->setShowZeroAxis(false);
+ plotH.getXAxis()->setShowZeroAxis(false);
+ plotH.getYAxis()->setShowZeroAxis(false);
+ });
+ app.addExportStepFunctor([&](){
+ for (auto g: gV) {
+ g->setDrawBaseline(true);
+ }
+ for (auto g: gH) {
+ g->setDrawBaseline(true);
+ }
+ plotV.getXAxis()->setShowZeroAxis(false);
+ plotV.getYAxis()->setShowZeroAxis(false);
+ plotH.getXAxis()->setShowZeroAxis(false);
+ plotH.getYAxis()->setShowZeroAxis(false);
+ });
return app.exec();
}
diff --git a/examples/impulsesplot/impulsesplot.cpp b/examples/impulsesplot/impulsesplot.cpp
index 6ba815822b..01b35f11a1 100644
--- a/examples/impulsesplot/impulsesplot.cpp
+++ b/examples/impulsesplot/impulsesplot.cpp
@@ -80,7 +80,7 @@ int main(int argc, char* argv[])
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
JKQTPlotter plot;
- drawPlot(plot);
+ auto grV=drawPlot(plot);
plot.setWindowTitle("1: JKQTPImpulsesVerticalGraph");
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
@@ -94,7 +94,7 @@ int main(int argc, char* argv[])
grS->setSymbolSize(12);
JKQTPlotter plotH;
- drawPlot(plotH);
+ auto grH=drawPlot(plotH);
plotH.setWindowTitle("3: JKQTPImpulsesHorizontalGraph");
plotH.resize(400/plot.devicePixelRatioF(),600/plot.devicePixelRatioF());
@@ -109,6 +109,35 @@ int main(int argc, char* argv[])
grEH->setLineWidth(4);
plotEH.resize(400/plot.devicePixelRatioF(),600/plot.devicePixelRatioF());
+ app.addExportStepFunctor([&]() {
+ grV->setDrawBaseline(false);
+ grS->setDrawBaseline(false);
+ grH->setDrawBaseline(false);
+ grE->setDrawBaseline(false);
+ grEH->setDrawBaseline(false);
+
+ plot.getXAxis()->setShowZeroAxis(false);
+ plot.getYAxis()->setShowZeroAxis(false);
+
+ plotE.getXAxis()->setShowZeroAxis(false);
+ plotE.getYAxis()->setShowZeroAxis(false);
+
+ plotEH.getXAxis()->setShowZeroAxis(false);
+ plotEH.getYAxis()->setShowZeroAxis(false);
+
+ plotH.getXAxis()->setShowZeroAxis(false);
+ plotH.getYAxis()->setShowZeroAxis(false);
+
+ plotS.getXAxis()->setShowZeroAxis(false);
+ plotS.getYAxis()->setShowZeroAxis(false);
+ });
+ app.addExportStepFunctor([&]() {
+ grV->setDrawBaseline(true);
+ grS->setDrawBaseline(true);
+ grH->setDrawBaseline(true);
+ grE->setDrawBaseline(true);
+ grEH->setDrawBaseline(true);
+ });
return app.exec();
}
diff --git a/examples/libexampletools/jkqtpexampleapplication.cpp b/examples/libexampletools/jkqtpexampleapplication.cpp
index 18d47e3dc6..89fb2767c4 100644
--- a/examples/libexampletools/jkqtpexampleapplication.cpp
+++ b/examples/libexampletools/jkqtpexampleapplication.cpp
@@ -195,10 +195,9 @@ int JKQTPExampleApplication::exec()
QWidget* w=widgets[i];
if (w->isVisible()) {
saveWidget(w, iVisible);
+ iVisible++;
}
-
}
- iVisible++;
}
return 0;
} else if (saveScreenshot||saveSmallScreenshot||saveScreenshotPlot||saveSmallScreenshotPlot) {
diff --git a/lib/jkqtplotter/graphs/jkqtpbarchart.cpp b/lib/jkqtplotter/graphs/jkqtpbarchart.cpp
index e02cf228b0..c758f4bfee 100644
--- a/lib/jkqtplotter/graphs/jkqtpbarchart.cpp
+++ b/lib/jkqtplotter/graphs/jkqtpbarchart.cpp
@@ -61,6 +61,9 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
int imax=0;
int imin=0;
+ double left=-1e6;
+ double right=1e6;
+ bool firstXY=true;
if (getIndexRange(imin, imax)) {
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
@@ -121,6 +124,14 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
painter.setPen(p);
}
const QRectF r(QPointF(x, y), QPointF(xx, yy));
+ if (firstXY) {
+ left=r.left();
+ right=r.right();
+ } else {
+ left=qMin(left, r.left());
+ right=qMax(right, r.right());
+ }
+ firstXY=false;
if (usesCustomDrawFunctor()) {
if (m_customDrawFunctor) {
m_customDrawFunctor(painter, r, QPointF(xv,yv), Qt::Vertical, this);
@@ -145,6 +156,12 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
}
}
+ if (getDrawBaseline() && left!=right && !hasStackParent()) {
+ painter.setPen(baselineStyle().getLinePen(painter, parent));
+ const double yb=transformY(getBaseline());
+ if (JKQTPIsOKFloat(yb)) painter.drawLine(left, yb, right, yb);
+ }
+
}
drawErrorsAfter(painter);
}
@@ -225,6 +242,9 @@ void JKQTPBarHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
int imax=0;
int imin=0;
+ double top=0;
+ double bottom=0;
+ bool firstXY=true;
if (getIndexRange(imin, imax)) {
double x0=transformX(0);
@@ -288,6 +308,14 @@ void JKQTPBarHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
painter.setPen(p);
}
const QRectF r(QPointF(x, y), QPointF(xx, yy));
+ if (firstXY) {
+ top=r.top();
+ bottom=r.bottom();
+ } else {
+ top=qMin(top, r.top());
+ bottom=qMax(bottom, r.bottom());
+ }
+ firstXY=false;
if (usesCustomDrawFunctor()) {
if (m_customDrawFunctor) {
m_customDrawFunctor(painter, r, QPointF(xv,yv), Qt::Horizontal, this);
@@ -309,6 +337,11 @@ void JKQTPBarHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
}
}
}
+ if (getDrawBaseline() && top!=bottom && !hasStackParent()) {
+ painter.setPen(baselineStyle().getLinePen(painter, parent));
+ const double xb=transformX(getBaseline());
+ if (JKQTPIsOKFloat(xb)) painter.drawLine(xb,top,xb,bottom);
+ }
}
drawErrorsAfter(painter);
}
diff --git a/lib/jkqtplotter/graphs/jkqtpbarchartbase.cpp b/lib/jkqtplotter/graphs/jkqtpbarchartbase.cpp
index d23351f787..a1aaf7a877 100644
--- a/lib/jkqtplotter/graphs/jkqtpbarchartbase.cpp
+++ b/lib/jkqtplotter/graphs/jkqtpbarchartbase.cpp
@@ -40,11 +40,15 @@ JKQTPBarGraphBase::JKQTPBarGraphBase(JKQTBasePlotter* parent):
m_fillMode(FillMode::SingleFilling),
m_useCustomDrawFunctor(false),
m_lineColorDerivationModeForSpecialFill(parent->getCurrentPlotterStyle().graphsStyle.barchartStyle.graphColorDerivationMode),
- rectRadiusAtBaseline(0),rectRadiusAtValue(0)
+ rectRadiusAtBaseline(0),rectRadiusAtValue(0),
+ m_drawBaseline(parent->getCurrentPlotterStyle().graphsStyle.barchartStyle.drawBaseline)
{
initFillStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Barchart);
initLineStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Barchart);
m_fillStyleBelow.initFillStyleInvertedColor(this);
+ m_baselineStyle.setLineColor(parent->getCurrentPlotterStyle().xAxisStyle.colorZeroAxis);
+ m_baselineStyle.setLineStyle(Qt::SolidLine);
+ m_baselineStyle.setLineWidth(parent->getCurrentPlotterStyle().xAxisStyle.lineWidthZeroAxis);
rectRadiusAtBaseline= parent->getCurrentPlotterStyle().graphsStyle.barchartStyle.defaultRectRadiusAtBaseline;
rectRadiusAtValue= parent->getCurrentPlotterStyle().graphsStyle.barchartStyle.defaultRectRadiusAtValue;
}
@@ -167,6 +171,26 @@ void JKQTPBarGraphBase::setWidth(double __value)
this->width = __value;
}
+void JKQTPBarGraphBase::setDrawBaseline(bool __value)
+{
+ m_drawBaseline=__value;
+}
+
+bool JKQTPBarGraphBase::getDrawBaseline() const
+{
+ return this->m_drawBaseline;
+}
+
+JKQTPGraphLineStyleMixin &JKQTPBarGraphBase::baselineStyle()
+{
+ return m_baselineStyle;
+}
+
+const JKQTPGraphLineStyleMixin &JKQTPBarGraphBase::baselineStyle() const
+{
+ return m_baselineStyle;
+}
+
double JKQTPBarGraphBase::getWidth() const
{
return this->width;
diff --git a/lib/jkqtplotter/graphs/jkqtpbarchartbase.h b/lib/jkqtplotter/graphs/jkqtpbarchartbase.h
index 569295a705..0524e6a153 100644
--- a/lib/jkqtplotter/graphs/jkqtpbarchartbase.h
+++ b/lib/jkqtplotter/graphs/jkqtpbarchartbase.h
@@ -163,6 +163,12 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
JKQTPColorDerivationMode getLineColorDerivationModeForSpecialFill() const;
/** \copydoc m_useCustomDrawFunctor */
bool usesCustomDrawFunctor() const;
+ /** \copydoc m_drawBaseline */
+ bool getDrawBaseline() const;
+ /** \copydoc m_baselineStyle */
+ JKQTPGraphLineStyleMixin &baselineStyle();
+ /** \copydoc m_baselineStyle */
+ const JKQTPGraphLineStyleMixin& baselineStyle() const;
public slots:
/** \copydoc m_fillMode */
@@ -201,6 +207,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
void setShift(double __value);
/** \copydoc width */
void setWidth(double __value);
+ /** \copydoc m_drawBaseline */
+ void setDrawBaseline(bool __value);
/** \copydoc rectRadiusAtValue */
void setRectRadiusAtValue(double __value);
@@ -249,6 +257,20 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
double rectRadiusAtValue;
/** \brief corner radius (in pt) for bars at the "baseline" end */
double rectRadiusAtBaseline;
+ /** \brief if m_drawBaseline \c ==true then this style is used to draw the baseline
+ *
+ * \see baselineStyle() , setDrawBaseline() , m_drawBaseline
+ */
+ JKQTPGraphLineStyleMixin m_baselineStyle;
+ /** \brief indicates whether to draw a line with style m_baselineStyle at the baseline-value
+ *
+ * \image html JKQTPBarVerticalGraphBaseline.png "setDrawBaseline(true);"
+ *
+ * \image html JKQTPBarVerticalGraphNoBaseline.png "setDrawBaseline(false);"
+ *
+ * \see baselineStyle() , setDrawBaseline() , m_baselineStyle
+ */
+ bool m_drawBaseline;
/** \brief specifies how the area of the graph is filles
*
* \note If any fill style other than FillStyle::SingleFill is used, the peroperty m_lineColorDerivationModeForSpecialFill
diff --git a/lib/jkqtplotter/graphs/jkqtpimpulses.cpp b/lib/jkqtplotter/graphs/jkqtpimpulses.cpp
index c001e62243..9eef1c2aad 100644
--- a/lib/jkqtplotter/graphs/jkqtpimpulses.cpp
+++ b/lib/jkqtplotter/graphs/jkqtpimpulses.cpp
@@ -25,8 +25,6 @@
#include
#include
#include "jkqtplotter/jkqtptools.h"
-#include "jkqtplotter/graphs/jkqtpimage.h"
-#include "jkqtplotter/jkqtpbaseelements.h"
#include "jkqtplotter/jkqtplotter.h"
#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgzgetCurrentPlotterStyle().graphsStyle.impulseStyle.drawBaseline)
{
initLineStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Impulses);
initSymbolStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Impulses);
+ m_baselineStyle=*this;
}
QColor JKQTPImpulsesGraphBase::getKeyLabelColor() const {
@@ -53,6 +54,7 @@ void JKQTPImpulsesGraphBase::setColor(QColor c)
setSymbolFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphsStyle.impulseStyle.fillColorDerivationMode, c));
c.setAlphaF(0.5);
setHighlightingLineColor(c);
+ m_baselineStyle.setLineColor(c);
}
void JKQTPImpulsesGraphBase::setDrawSymbols(bool __value)
@@ -65,6 +67,25 @@ bool JKQTPImpulsesGraphBase::getDrawSymbols() const
return drawSymbols;
}
+void JKQTPImpulsesGraphBase::setDrawBaseline(bool __value)
+{
+ m_drawBaseline=__value;
+}
+
+bool JKQTPImpulsesGraphBase::getDrawBaseline() const
+{
+ return this->m_drawBaseline;
+}
+
+JKQTPGraphLineStyleMixin &JKQTPImpulsesGraphBase::baselineStyle()
+{
+ return m_baselineStyle;
+}
+
+const JKQTPGraphLineStyleMixin &JKQTPImpulsesGraphBase::baselineStyle() const
+{
+ return m_baselineStyle;
+}
bool JKQTPImpulsesGraphBase::getValuesMinMax(double &mmin, double &mmax, double &smallestGreaterZero)
{
@@ -179,6 +200,9 @@ void JKQTPImpulsesHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
int imax=0;
int imin=0;
+ double bottom=-1e6;
+ double top=1e6;
+ bool firstXY=true;
if (getIndexRange(imin, imax)) {
double x0=transformX(getBaseline());
@@ -197,7 +221,14 @@ void JKQTPImpulsesHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
if (JKQTPIsOKFloat(xv) && JKQTPIsOKFloat(yv)) {
const double x=transformX(xv);
const double y=transformY(yv);
-
+ if (firstXY) {
+ bottom=y;
+ top=y;
+ } else {
+ bottom=qMax(bottom, y);
+ top=qMin(top, y);
+ }
+ firstXY=false;
lines.append(QLineF(x0, y, x, y));
points.append(QPointF(x,y));
@@ -212,6 +243,11 @@ void JKQTPImpulsesHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
}
}
}
+ if (getDrawBaseline() && top!=bottom) {
+ painter.setPen(baselineStyle().getLinePen(painter, parent));
+ const double xb=transformX(getBaseline());
+ if (JKQTPIsOKFloat(xb)) painter.drawLine(xb,top,xb,bottom);
+ }
}
drawErrorsAfter(painter);
@@ -322,13 +358,15 @@ void JKQTPImpulsesVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
int imax=0;
int imin=0;
+ double left=-1e6;
+ double right=1e6;
+ bool firstXY=true;
if (getIndexRange(imin, imax)) {
double y0=transformY(getBaseline());
if (parent->getYAxis()->isLogAxis()) {
- y0=transformY(parent->getYAxis()->getMin());
if (getBaseline()>0 && getBaseline()>parent->getYAxis()->getMin()) y0=transformY(getBaseline());
else y0=transformY(parent->getYAxis()->getMin());
}
@@ -342,6 +380,14 @@ void JKQTPImpulsesVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
if (JKQTPIsOKFloat(xv) && JKQTPIsOKFloat(yv) ) {
const double x=transformX(xv);
const double y=transformY(yv);
+ if (firstXY) {
+ left=x;
+ right=x;
+ } else {
+ left=qMin(left, x);
+ right=qMax(right, x);
+ }
+ firstXY=false;
lines.append(QLineF(x, y0, x, y));
@@ -358,6 +404,11 @@ void JKQTPImpulsesVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
}
}
}
+ if (getDrawBaseline() && left!=right) {
+ painter.setPen(baselineStyle().getLinePen(painter, parent));
+ const double yb=transformY(getBaseline());
+ if (JKQTPIsOKFloat(yb)) painter.drawLine(left, yb, right, yb);
+ }
}
drawErrorsAfter(painter);
diff --git a/lib/jkqtplotter/graphs/jkqtpimpulses.h b/lib/jkqtplotter/graphs/jkqtpimpulses.h
index 0ee7b84efb..79760ae3b9 100644
--- a/lib/jkqtplotter/graphs/jkqtpimpulses.h
+++ b/lib/jkqtplotter/graphs/jkqtpimpulses.h
@@ -30,7 +30,11 @@
/** \brief This is a base class for all impulse graphs
* \ingroup jkqtplotter_sticks
*
- * \image html JKQTPImpulsesVerticalGraph.png
+ * \image html JKQTPImpulsesVerticalGraph.png "default style for impulse graphs"
+ *
+ * \image html JKQTPImpulsesVerticalGraph_Symbols.png "setDrawSymbols(true);"
+ *
+ * \image html JKQTPImpulsesVerticalGraphBaseline.png "setDrawBaseline(true);"
*
* \see JKQTPImpulsesHorizontalGraph, JKQTPImpulsesVerticalGraph
*/
@@ -45,6 +49,13 @@ public:
virtual QColor getKeyLabelColor() const override;
/** \copydoc drawSymbols */
bool getDrawSymbols() const;
+ /** \copydoc m_drawBaseline */
+ bool getDrawBaseline() const;
+ /** \copydoc m_baselineStyle */
+ JKQTPGraphLineStyleMixin &baselineStyle();
+ /** \copydoc m_baselineStyle */
+ const JKQTPGraphLineStyleMixin& baselineStyle() const;
+
public slots:
/** \brief color of symbols and impulses in one call */
@@ -52,14 +63,29 @@ public slots:
/** \copydoc drawSymbols */
void setDrawSymbols(bool __value);
+ /** \copydoc m_drawBaseline */
+ void setDrawBaseline(bool __value);
protected:
/** \brief indicates whether to draw symbols at the top of the impulse
- *
- * \image html impulsesplot_symbols.png
- */
+ *
+ * \image html JKQTPImpulsesVerticalGraph_Symbols.png "setDrawSymbols(true)"
+ */
bool drawSymbols;
+ /** \brief if m_drawBaseline \c ==true then this style is used to draw the baseline
+ *
+ * \see baselineStyle() , setDrawBaseline() , m_drawBaseline
+ */
+ JKQTPGraphLineStyleMixin m_baselineStyle;
+ /** \brief indicates whether to draw a line with style m_baselineStyle at the baseline-value
+ *
+ * \image html JKQTPImpulsesVerticalGraphBaseline.png "setDrawBaseline(true);"
+ * \image html JKQTPImpulsesVerticalGraphNoBaseline.png "setDrawBaseline(false);"
+ *
+ * \see baselineStyle() , setDrawBaseline() , m_baselineStyle
+ */
+ bool m_drawBaseline;
/** \brief get the maximum and minimum value in the impulse-elongation (i.e. value) direction of the graph
*
diff --git a/lib/jkqtplotter/jkqtpgraphsbasestyle.cpp b/lib/jkqtplotter/jkqtpgraphsbasestyle.cpp
index bee02a8eca..2e5ab79967 100644
--- a/lib/jkqtplotter/jkqtpgraphsbasestyle.cpp
+++ b/lib/jkqtplotter/jkqtpgraphsbasestyle.cpp
@@ -201,7 +201,7 @@ JKQTGraphsBaseStyle::JKQTGraphsBaseStyle(const JKQTBasePlotterStyle& parent):
barchartStyle(parent),
boxplotStyle(JKQTPPlotStyleType::Boxplot, parent),
filledStyle(JKQTPPlotStyleType::Filled, parent),
- impulseStyle(JKQTPPlotStyleType::Impulses, parent),
+ impulseStyle(parent),
geometricStyle(parent),
annotationStyle(parent),
defaultPalette(JKQTPMathImageColorPalette::JKQTPMathImageMATLAB)
@@ -290,7 +290,7 @@ void JKQTGraphsBaseStyle::loadSettings(const QSettings &settings, const QString
barchartStyle.loadSettings(settings, group+"graphs_barchart/", JKQTBarchartSpecificStyleProperties(parent, defaultGraphStyle));
boxplotStyle.loadSettings(settings, group+"graphs_boxplot/", JKQTGraphsSpecificStyleProperties(JKQTPPlotStyleType::Boxplot, defaultGraphStyle));
filledStyle.loadSettings(settings, group+"graphs_filled/", JKQTGraphsSpecificStyleProperties(JKQTPPlotStyleType::Filled, defaultGraphStyle));
- impulseStyle.loadSettings(settings, group+"graphs_impulses/",JKQTGraphsSpecificStyleProperties(JKQTPPlotStyleType::Impulses, defaultGraphStyle));
+ impulseStyle.loadSettings(settings, group+"graphs_impulses/", JKQTImpulseSpecificStyleProperties(parent, defaultGraphStyle));
geometricStyle.loadSettings(settings, group+"graphs_geometric/", JKQTGeometricSpecificStyleProperties(parent, defaultGraphStyle));
annotationStyle.loadSettings(settings, group+"graphs_annotation/", JKQTAnnotationsSpecificStyleProperties(parent, defaultGraphStyle));
@@ -358,7 +358,8 @@ const JKQTGraphsSpecificStyleProperties &JKQTGraphsBaseStyle::getGraphStyleByTyp
JKQTBarchartSpecificStyleProperties::JKQTBarchartSpecificStyleProperties(const JKQTBasePlotterStyle& parent):
JKQTGraphsSpecificStyleProperties(JKQTPPlotStyleType::Barchart, parent),
defaultRectRadiusAtValue(0),
- defaultRectRadiusAtBaseline(0)
+ defaultRectRadiusAtBaseline(0),
+ drawBaseline(false)
{
}
@@ -366,7 +367,8 @@ JKQTBarchartSpecificStyleProperties::JKQTBarchartSpecificStyleProperties(const J
JKQTBarchartSpecificStyleProperties::JKQTBarchartSpecificStyleProperties(const JKQTBasePlotterStyle& parent, const JKQTGraphsSpecificStyleProperties &other):
JKQTGraphsSpecificStyleProperties(JKQTPPlotStyleType::Barchart, other),
defaultRectRadiusAtValue(0),
- defaultRectRadiusAtBaseline(0)
+ defaultRectRadiusAtBaseline(0),
+ drawBaseline(false)
{
}
@@ -376,6 +378,7 @@ void JKQTBarchartSpecificStyleProperties::loadSettings(const QSettings &settings
JKQTGraphsSpecificStyleProperties::loadSettings(settings, group, defaultStyle);
defaultRectRadiusAtValue=settings.value(group+"radius_at_value", defaultStyle.defaultRectRadiusAtValue).toDouble();
defaultRectRadiusAtBaseline=settings.value(group+"radius_at_baseline", defaultStyle.defaultRectRadiusAtBaseline).toDouble();
+ drawBaseline=settings.value(group+"draw_baseline", defaultStyle.drawBaseline).toBool();
}
void JKQTBarchartSpecificStyleProperties::saveSettings(QSettings &settings, const QString &group) const
@@ -383,6 +386,35 @@ void JKQTBarchartSpecificStyleProperties::saveSettings(QSettings &settings, cons
JKQTGraphsSpecificStyleProperties::saveSettings(settings, group);
settings.setValue(group+"radius_at_value", defaultRectRadiusAtValue);
settings.setValue(group+"radius_at_baseline", defaultRectRadiusAtBaseline);
+ settings.setValue(group+"draw_baseline", drawBaseline);
+
+}
+
+
+JKQTImpulseSpecificStyleProperties::JKQTImpulseSpecificStyleProperties(const JKQTBasePlotterStyle& parent):
+ JKQTGraphsSpecificStyleProperties(JKQTPPlotStyleType::Impulses, parent),
+ drawBaseline(false)
+{
+
+}
+
+JKQTImpulseSpecificStyleProperties::JKQTImpulseSpecificStyleProperties(const JKQTBasePlotterStyle& parent, const JKQTGraphsSpecificStyleProperties &other):
+ JKQTGraphsSpecificStyleProperties(JKQTPPlotStyleType::Impulses, other),
+ drawBaseline(false)
+{
+
+}
+
+void JKQTImpulseSpecificStyleProperties::loadSettings(const QSettings &settings, const QString &group, const JKQTImpulseSpecificStyleProperties &defaultStyle)
+{
+ JKQTGraphsSpecificStyleProperties::loadSettings(settings, group, defaultStyle);
+ drawBaseline=settings.value(group+"draw_baseline", defaultStyle.drawBaseline).toBool();
+}
+
+void JKQTImpulseSpecificStyleProperties::saveSettings(QSettings &settings, const QString &group) const
+{
+ JKQTGraphsSpecificStyleProperties::saveSettings(settings, group);
+ settings.setValue(group+"draw_baseline", drawBaseline);
}
diff --git a/lib/jkqtplotter/jkqtpgraphsbasestyle.h b/lib/jkqtplotter/jkqtpgraphsbasestyle.h
index b013d5f4a8..c71cf9ef36 100644
--- a/lib/jkqtplotter/jkqtpgraphsbasestyle.h
+++ b/lib/jkqtplotter/jkqtpgraphsbasestyle.h
@@ -244,11 +244,53 @@ public:
double defaultRectRadiusAtValue;
/** \brief corner radius (in pt) for bars at the "baseline" end */
double defaultRectRadiusAtBaseline;
+ /** \brief indicates whether to draw a baseline (style is derived from axis style) */
+ bool drawBaseline;
};
+
+/** \brief Support Class for JKQTBasePlotter, which summarizes all properties that define the visual styling of impulse/stick graph elements
+* \ingroup jkqtpplotter_styling_classes
+*
+* \see JKQTBasePlotter, \ref jkqtpplotter_styling
+*/
+class JKQTPLOTTER_LIB_EXPORT JKQTImpulseSpecificStyleProperties: public JKQTGraphsSpecificStyleProperties {
+#ifndef JKQTPLOTTER_WORKAROUND_QGADGET_BUG
+ Q_GADGET
+#endif
+public:
+ JKQTImpulseSpecificStyleProperties(const JKQTBasePlotterStyle& parent);
+ JKQTImpulseSpecificStyleProperties(const JKQTBasePlotterStyle& parent, const JKQTGraphsSpecificStyleProperties& other);
+ JKQTImpulseSpecificStyleProperties(const JKQTImpulseSpecificStyleProperties& other)=default;
+ JKQTImpulseSpecificStyleProperties(JKQTImpulseSpecificStyleProperties&& other)=default;
+ JKQTImpulseSpecificStyleProperties& operator=(const JKQTImpulseSpecificStyleProperties& other)=default;
+ JKQTImpulseSpecificStyleProperties& operator=(JKQTImpulseSpecificStyleProperties&& other)=default;
+
+
+ /** \brief loads the plot properties from a QSettings object
+ *
+ * \param settings QSettings-object to read from
+ * \param group Group in the QSettings-object to read from
+ * \param defaultStyle If a setting cannot be found in \a settings, default values are taken from this object
+ * By default, this is a default-constructed object
+ */
+ void loadSettings(const QSettings &settings, const QString& group, const JKQTImpulseSpecificStyleProperties &defaultStyle);
+
+ /** \brief saves the plot properties into a QSettings object.
+ *
+ * \param settings QSettings-object to save to
+ * \param group Group in the QSettings-object to save to
+ */
+ void saveSettings(QSettings& settings, const QString& group) const;
+
+ /** \brief indicates whether to draw a baseline (style is derived from axis style) */
+ bool drawBaseline;
+
+
+};
/** \brief Support Class for JKQTBasePlotter, which summarizes all properties that define the visual styling of a JKQTBasePlotter
* \ingroup jkqtpplotter_styling_classes
*
@@ -297,7 +339,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTGraphsBaseStyle {
/** \brief styling options for filled graphs */
JKQTGraphsSpecificStyleProperties filledStyle;
/** \brief styling options for impulses graphs */
- JKQTGraphsSpecificStyleProperties impulseStyle;
+ JKQTImpulseSpecificStyleProperties impulseStyle;
/** \brief styling options for geometric elements */
JKQTGeometricSpecificStyleProperties geometricStyle;
/** \brief styling options for annotation elements */
diff --git a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h
index 5fa877fb0d..4d76478115 100644
--- a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h
+++ b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h
@@ -125,6 +125,24 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGraphLineStyleMixin {
QColor getHighlightingLineColor() const;
+
+
+ /** \brief returns the linewidth for drawing lines in a key entry with \a keyRect for the symbol, using \a painter and \a parent . */
+ double getKeyLineWidthPx(JKQTPEnhancedPainter &painter, const QRectF &keyRect, const JKQTBasePlotter *parent) const;
+
+ /** \brief constructs a QPen from the line styling properties */
+ QPen getLinePen(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) const;
+ /** \brief constructs a QPen from the line styling properties, suitable for drawing rectangles with sharp edges */
+ QPen getLinePenForRects(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) const;
+ /** \brief constructs a QPen from the line styling properties */
+ QPen getHighlightingLinePen(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) const;
+ /** \brief constructs a QPen from the line styling properties, suitable for drawing rectangle with sharp corners */
+ QPen getHighlightingLinePenForRects(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) const;
+ /** \brief constructs a QPen from the line styling properties, but uses getKeyLineWidthPx() for the width, i.e. constructs a pen for drawing lines in key-symbols */
+ QPen getKeyLinePen(JKQTPEnhancedPainter &painter, const QRectF &rect, JKQTBasePlotter *parent) const;
+
+
+
#ifndef JKQTPLOTTER_WORKAROUND_QGADGET_BUG
Q_PROPERTY(QColor highlightingLineColor MEMBER m_highlightingLineColor READ getHighlightingLineColor WRITE setHighlightingLineColor)
Q_PROPERTY(QColor lineColor MEMBER m_lineColor READ getLineColor WRITE setLineColor)
@@ -139,19 +157,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGraphLineStyleMixin {
/** \brief line pen for the highlighted look */
QColor m_highlightingLineColor;
protected:
- /** \brief returns the linewidth for drawing lines in a key entry with \a keyRect for the symbol, using \a painter and \a parent . */
- double getKeyLineWidthPx(JKQTPEnhancedPainter &painter, const QRectF &keyRect, const JKQTBasePlotter *parent) const;
-
- /** \brief constructs a QPen from the line styling properties */
- QPen getLinePen(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) const;
- /** \brief constructs a QPen from the line styling properties, suitable for drawing rectangles with sharp edges */
- QPen getLinePenForRects(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) const;
- /** \brief constructs a QPen from the line styling properties */
- QPen getHighlightingLinePen(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) const;
- /** \brief constructs a QPen from the line styling properties, suitable for drawing rectangle with sharp corners */
- QPen getHighlightingLinePenForRects(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) const;
- /** \brief constructs a QPen from the line styling properties, but uses getKeyLineWidthPx() for the width, i.e. constructs a pen for drawing lines in key-symbols */
- QPen getKeyLinePen(JKQTPEnhancedPainter &painter, const QRectF &rect, JKQTBasePlotter *parent) const;
};
diff --git a/screenshots/parsedfunctionplot.png b/screenshots/parsedfunctionplot.png
index 4cf9c0dbb7..6a935aab88 100644
Binary files a/screenshots/parsedfunctionplot.png and b/screenshots/parsedfunctionplot.png differ
diff --git a/screenshots/parsedfunctionplot_small.png b/screenshots/parsedfunctionplot_small.png
index 959d93b813..638ad69fab 100644
Binary files a/screenshots/parsedfunctionplot_small.png and b/screenshots/parsedfunctionplot_small.png differ