diff --git a/JKQtPlotterBuildAllExamples.pro b/JKQtPlotterBuildAllExamples.pro
index 9a120f9125..e19977d62a 100644
--- a/JKQtPlotterBuildAllExamples.pro
+++ b/JKQtPlotterBuildAllExamples.pro
@@ -98,5 +98,6 @@ defineTest(addTest) {
addTest(multiplot)
addTest(user_interaction)
addTest(styling)
-#addTest(distributionplot)
+addTest(styledboxplot)
+addTest(distributionplot)
diff --git a/doc/dox/examples_and_tutorials.dox b/doc/dox/examples_and_tutorials.dox
index 6b33131543..914e18011f 100644
--- a/doc/dox/examples_and_tutorials.dox
+++ b/doc/dox/examples_and_tutorials.dox
@@ -78,6 +78,12 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
\image html test_styling_small.png
+ | \subpage JKQTPlotterStyling
+ | Modifying different Aspects of the Styling of JKQTPlotter
diff --git a/doc/dox/jkqtplotter.dox b/doc/dox/jkqtplotter.dox
index fc099f97ea..2208b73bdf 100644
--- a/doc/dox/jkqtplotter.dox
+++ b/doc/dox/jkqtplotter.dox
@@ -8,7 +8,7 @@ C++ standard library.
\defgroup jkqtpplotterclasses_tools Support Classes/Structs/Functions for JKQTPlotter&JKQTBasePlotter
\ingroup jkqtptools
-\defgroup tools_math Tools for Mathematical Computations & Equation Parsing
+\defgroup jkqtptools_math Tools for Mathematical Computations & Equation Parsing
\ingroup jkqtptools
\defgroup jkqtptools_string String Tool Functions
@@ -20,7 +20,7 @@ C++ standard library.
\defgroup jkqtptools_qtwidgets Additional Widgets for Qt
\ingroup jkqtptools
-\defgroup jkqtptools_drawing Drawing Tools
+\defgroup jkqtptools_drawing Drawing & Graphics Tools
\ingroup jkqtptools
\defgroup jkqtptools_debugging Debugging Tools
diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox
index 7f2538c2cc..716266543f 100644
--- a/doc/dox/whatsnew.dox
+++ b/doc/dox/whatsnew.dox
@@ -41,6 +41,8 @@ Changes, compared to \ref WHATSNEW_V2018_08 "v2018.08" include:
new: JKQTPXYParametrizedScatterGraph: added functors to transform column values into symbol type+size and line-width to give even more control
new: user-interaction tool that shows coordinates of data points near the current mouse position (when mouse is dragged, while mouse button is pressed) \see jkqtpmdaToolTipForClosestDataPoint
new: user-interaction tool that measures distances and angles when mouse is dragged, while mouse button is pressed) \see jkqtpmdaRuler
+ new: advanced styling options for boxplots + example for the styling: \ref JKQTPlotterBoxplotStyling
+ new: notched boxplots
changed: removed old selection-code and replaced by general highlighting feature
changed: JKQTPStepHorizontalGraph has been renamed to JKQTPSpecialLineHorizontalGraph (vertical variants also) and have gained additional features (baseline for filling and drawing of symbols)
changed: filled curve graphs (e.g. JKQTPSpecialLineHorizontalGraph) are now merely a specializedly initialized JKQTPSpecialLineHorizontalGraph
diff --git a/doc/images/boxplots.png b/doc/images/boxplots.png
index f30d446720..6a1b1bf5dd 100644
Binary files a/doc/images/boxplots.png and b/doc/images/boxplots.png differ
diff --git a/doc/images/plot_boxplothorizontalelement.png b/doc/images/plot_boxplothorizontalelement.png
new file mode 100644
index 0000000000..6a1b1bf5dd
Binary files /dev/null and b/doc/images/plot_boxplothorizontalelement.png differ
diff --git a/doc/images/plot_boxplotverticalelement.png b/doc/images/plot_boxplotverticalelement.png
new file mode 100644
index 0000000000..8b5aa19d74
Binary files /dev/null and b/doc/images/plot_boxplotverticalelement.png differ
diff --git a/examples/README.md b/examples/README.md
index cd226e6c44..4b06f5f6e6 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -31,7 +31,9 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|:-------------:| ------------- | ------------- |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_logaxes_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_logaxes) | [logarithmic axes](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_logaxes) | `JKQTPXYLineGraph` and `JKQTPGeoText` C++ vector of data logarithmic axes and styling plot line styles internal LaTeX parser add commenting text to a graph |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_dateaxes_small.png) ![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_dateaxes_dates_small.png) ![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_dateaxes_timeaxis_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_dateaxes) | [date/time axes](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_dateaxes) | `JKQTPXYLineGraph` and `JKQTPFilledVerticalRangeGraph` C++ vector of data date/time axes plot min/max range graph internal LaTeX parser data from CSV files |
-| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_advancedlineandfillstyling_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_advancedlineandfillstyling) | [logarithmic axes](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_advancedlineandfillstyling) | `JKQTPXYLineGraph`, `JKQTPSpecialLineHorizontalGraph` and `JKQTPBarVerticalGraph` C++ vector of data advanced line styling and filling |
+| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_advancedlineandfillstyling_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_advancedlineandfillstyling) | [advanced line and fill styling](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_advancedlineandfillstyling) | `JKQTPXYLineGraph`, `JKQTPSpecialLineHorizontalGraph` and `JKQTPBarVerticalGraph` C++ vector of data advanced line styling and filling |
+| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/test_styledboxplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_styledboxplot) | [Styling of Boxplots](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_styledboxplot) | Modifying different Aspects of the Styling of boxplots |
+| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/test_styling_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_styling) | [Styling of JKQTPlotter](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_styling) | Modifying different Aspects of the Styling of JKQTPlotter |
## Image data Plots
diff --git a/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.cpp b/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.cpp
index 253d8cfbc1..fae179fbfc 100644
--- a/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.cpp
+++ b/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.cpp
@@ -109,8 +109,8 @@ int main(int argc, char* argv[])
linearGrad.setColorAt(0.3, c2);
linearGrad.setColorAt(0.7, c3);
linearGrad.setColorAt(1, c4);
- linearGrad.setCoordinateMode(QGradient::ObjectBoundingMode);
// use this CoordinateMode, so the gradient fills the whole graph area
+ linearGrad.setCoordinateMode(QGradient::ObjectBoundingMode);
graphF2->setFillGradient(linearGrad);
// 5.4 fill barcharts with transparencies and make the surrounding line invisible (colored transparent)
diff --git a/examples/simpletest_boxplot/README.md b/examples/simpletest_boxplot/README.md
index ba3abee868..1f49cd5ed6 100644
--- a/examples/simpletest_boxplot/README.md
+++ b/examples/simpletest_boxplot/README.md
@@ -45,18 +45,22 @@ After adding all necessary data to the JKQTDatastore:
You can further style the plot by e.g. setting:
```.cpp
- // 4.1 make fill collor a lighter shade of the outline color
- graph->setFillColor(graphh->getColor().lighter());
- // 4.2 make whiskers dashed
- graph->setWhiskerLineStyle(Qt::DashLine);
- graph->setWhiskerLineColor(graph->getLineColor().darker());
- // 4.3 change mean symbol
- graph->setSymbolType(JKQTPFilledStar);
- graph->setSymbolFillColor(QColor("silver"));
- // 4.4 change median line color
- graph->setMedianLineColor(QColor("darkgreen"));
- // 4.5 change box width to 75% of distance
- graph->setBoxWidth(0.75);
+ // 6.1 make fill collor a lighter shade of the outline color
+ graphh->setFillColor(graphh->getLineColor().lighter());
+ // 6.2 make whiskers dashed
+ graphh->setWhiskerLineStyle(Qt::DashLine);
+ graphh->setWhiskerLineColor(graphh->getLineColor().darker());
+ // 6.3 make whiskers caps solid and thick
+ graphh->setWhiskerCapLineStyle(Qt::SolidLine);
+ graphh->setWhiskerCapLineColor(graphh->getLineColor().darker());
+ graphh->setWhiskerCapLineWidth(graphh->getLineWidth()*2.5);
+ // 6.4 change mean symbol
+ graphh->setMeanSymbolType(JKQTPFilledStar);
+ graphh->setMeanFillColor(QColor("silver"));
+ // 6.5 change median line color
+ graphh->setMedianLineColor(QColor("darkgreen"));
+ // 6.6 change box width to 75% of distance
+ graphh->setBoxWidthRelative(0.75);
```
The result looks like this:
diff --git a/examples/simpletest_boxplot/jkqtplotter_simpletest_boxplot.cpp b/examples/simpletest_boxplot/jkqtplotter_simpletest_boxplot.cpp
index 7097c20e84..9e13ed2aa0 100644
--- a/examples/simpletest_boxplot/jkqtplotter_simpletest_boxplot.cpp
+++ b/examples/simpletest_boxplot/jkqtplotter_simpletest_boxplot.cpp
@@ -85,13 +85,17 @@ int main(int argc, char* argv[])
// 6.2 make whiskers dashed
graphh->setWhiskerLineStyle(Qt::DashLine);
graphh->setWhiskerLineColor(graphh->getLineColor().darker());
- // 6.3 change mean symbol
- graphh->setSymbolType(JKQTPFilledStar);
- graphh->setSymbolFillColor(QColor("silver"));
- // 6.4 change median line color
+ // 6.3 make whiskers caps solid and thick
+ graphh->setWhiskerCapLineStyle(Qt::SolidLine);
+ graphh->setWhiskerCapLineColor(graphh->getLineColor().darker());
+ graphh->setWhiskerCapLineWidth(graphh->getLineWidth()*2.5);
+ // 6.4 change mean symbol
+ graphh->setMeanSymbolType(JKQTPFilledStar);
+ graphh->setMeanFillColor(QColor("silver"));
+ // 6.5 change median line color
graphh->setMedianLineColor(QColor("darkgreen"));
- // 6.5 change box width to 75% of distance
- graphh->setBoxWidth(0.75);
+ // 6.6 change box width to 75% of distance
+ graphh->setBoxWidthRelative(0.75);
// 7. add the graphs to the plot, so it is actually displayed
plot.addGraph(graph);
diff --git a/examples/test_distributionplot/README.md b/examples/test_distributionplot/README.md
index e375cd496a..ffaca77491 100644
--- a/examples/test_distributionplot/README.md
+++ b/examples/test_distributionplot/README.md
@@ -47,6 +47,7 @@ After adding all necessary data to the JKQTDatastore:
const double rndMedian=RANDVAL[RANDVAL.size()/2];
const double rndQ25=RANDVAL[RANDVAL.size()/4];
const double rndQ75=RANDVAL[RANDVAL.size()*3/4];
+ const double rndMedianConfidence=2.0*1.57*fabs(rndQ75-rndQ25)/sqrt(static_cast(NDATA));
// 3. make data available to JKQTPlotter by adding it to the internal datastore.
size_t columnRANDVAL=ds->addCopiedColumn(RANDVAL, "RANDVAL"); // copy random values
@@ -99,15 +100,16 @@ After adding all necessary data to the JKQTDatastore:
graphBoxPlot->setPercentile25(rndQ25);
graphBoxPlot->setMean(rndMean);
graphBoxPlot->setMedian(rndMedian);
+ graphBoxPlot->setMedianConfidenceIntervalWidth(rndMedianConfidence);
graphBoxPlot->setPercentile75(rndQ75);
graphBoxPlot->setMax(rndMax);
- graphBoxPlot->setBoxWidth(24);
- graphBoxPlot->setSymbolTypeSize(16);
- graphBoxPlot->setSymbolTypeWidth(2);
+ graphBoxPlot->setBoxWidthAbsolute(24);
+ graphBoxPlot->setMeanSize(16);
+ graphBoxPlot->setLineWidth(2);
graphBoxPlot->setTitle("Statistical Properties");
- graphBoxPlot->setColor(QColor("blue"));
+ graphBoxPlot->setBoxplotColor(QColor("blue"), plot.getPlotter());
// make fill collor a lighter shade of the outline color
- graphBoxPlot->setFillColor(graphBoxPlot->getColor().lighter(180));
+ graphBoxPlot->setFillColor(graphBoxPlot->getLineColor().lighter(180));
// make whiskers dashed
graphBoxPlot->setWhiskerLineStyle(Qt::DashLine);
diff --git a/examples/test_distributionplot/test_distributionplot.cpp b/examples/test_distributionplot/test_distributionplot.cpp
index 8e1c4c6654..0888ebcd89 100644
--- a/examples/test_distributionplot/test_distributionplot.cpp
+++ b/examples/test_distributionplot/test_distributionplot.cpp
@@ -61,6 +61,7 @@ int main(int argc, char* argv[])
const double rndMedian=RANDVAL[RANDVAL.size()/2];
const double rndQ25=RANDVAL[RANDVAL.size()/4];
const double rndQ75=RANDVAL[RANDVAL.size()*3/4];
+ const double rndMedianConfidence=2.0*1.57*fabs(rndQ75-rndQ25)/sqrt(static_cast(NDATA));
// 3. make data available to JKQTPlotter by adding it to the internal datastore.
size_t columnRANDVAL=ds->addCopiedColumn(RANDVAL, "RANDVAL"); // copy random values
@@ -112,15 +113,20 @@ int main(int argc, char* argv[])
graphBoxPlot->setPercentile25(rndQ25);
graphBoxPlot->setMean(rndMean);
graphBoxPlot->setMedian(rndMedian);
+ graphBoxPlot->setMedianConfidenceIntervalWidth(rndMedianConfidence);
graphBoxPlot->setPercentile75(rndQ75);
graphBoxPlot->setMax(rndMax);
- graphBoxPlot->setBoxWidth(24);
- graphBoxPlot->setSymbolTypeSize(16);
- graphBoxPlot->setSymbolTypeWidth(2);
+ graphBoxPlot->setBoxWidthAbsolute(24);
+ graphBoxPlot->setMeanSize(12);
+ graphBoxPlot->setMeanSymbolType(JKQTPCross);
+ graphBoxPlot->setLineWidth(2);
graphBoxPlot->setTitle("Statistical Properties");
- graphBoxPlot->setColor(QColor("blue"));
+ // set color of all elements
+ graphBoxPlot->setBoxplotColor(QColor("blue"), plot.getPlotter());
+ // change color of mean symbol
+ graphBoxPlot->setMeanColor(QColor("red"));
// make fill collor a lighter shade of the outline color
- graphBoxPlot->setFillColor(graphBoxPlot->getColor().lighter(180));
+ graphBoxPlot->setFillColor(graphBoxPlot->getLineColor().lighter(180));
// make whiskers dashed
graphBoxPlot->setWhiskerLineStyle(Qt::DashLine);
@@ -140,7 +146,7 @@ int main(int argc, char* argv[])
// 11. show plotter and make it a decent size
plot.show();
- plot.resize(800,800);
+ plot.resize(800,650);
return app.exec();
}
diff --git a/examples/test_styledboxplot/README.md b/examples/test_styledboxplot/README.md
new file mode 100644
index 0000000000..6b967df6fe
--- /dev/null
+++ b/examples/test_styledboxplot/README.md
@@ -0,0 +1,119 @@
+# Example (JKQTPlotter): Styling different aspects of boxplots {#JKQTPlotterBoxplotStyling}
+This project (see [`test_styledboxplot`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_styledboxplot) demonstrates how to style different aspects of boxplots and how to draw different types and styles of boxplots. For a simple introduction into how to use boxplots, see [Plotting Box Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_boxplot) and [Plotting a Statistical Distribution of Data](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_distributionplot).
+
+The link http://vita.had.co.nz/papers/boxplots.pdf leads to a paper that described the history and different types of boxplots.
+
+The source code of the main application can be found in [`test_styledboxplot.cpp`](test_styledboxplot.cpp).
+The major parts that are concerned with the styling are:
+
+```.cpp
+ // 2. create a basic boxplot
+ plot.addGraph(graphBoxPlot=new JKQTPBoxplotVerticalElement(&plot));
+ plot.addGraph(new JKQTPGeoText(&plot, x-dx/2.0, y0+9, "\\textbf{\\begin{matrix}basic boxplot\\\\\"Turkey's style\"\\end{matrix}}", 8, QColor("black")));
+ graphBoxPlot->setPos(x);
+ graphBoxPlot->setMin(y0+1);
+ graphBoxPlot->setPercentile25(y0+2.5);
+ graphBoxPlot->setMedian(y0+4);
+ graphBoxPlot->setPercentile75(y0+5.5);
+ graphBoxPlot->setMax(y0+8);
+ // set color of all elements
+ graphBoxPlot->setBoxplotColor(QColor("black"),QColor("white"), plot.getPlotter());
+
+ // ...
+ // ...
+
+ // 3. create a basic boxplot with mean as symbol
+ // ...
+ // set mean value to show mean symbol
+ graphBoxPlot->setMean(y0+3.5);
+ graphBoxPlot->setDrawMean(true);
+ graphBoxPlot->setMeanMode(JKQTPGraphBoxplotStyleMixin::MeanAsSymbol);
+ graphBoxPlot->setMeanColor(QColor("darkgreen"));
+ graphBoxPlot->setMeanSymbolType(JKQTPFilledTriangle);
+
+ // ...
+ // ...
+
+ // 4. create a basic boxplot with mean as line
+ // ...
+ // set mean value to show mean symbol
+ graphBoxPlot->setMean(y0+3.5);
+ graphBoxPlot->setDrawMean(true);
+ graphBoxPlot->setMeanMode(JKQTPGraphBoxplotStyleMixin::MeanAsLine);
+ graphBoxPlot->setMeanColor(QColor("darkgreen"));
+ graphBoxPlot->setMeanLineStyle(Qt::DashLine);
+ graphBoxPlot->setMeanLineWidth(2);
+
+ // ...
+ // ...
+
+ // 5. create a notched boxplot
+ // ...
+ // for a notched plot, you need to set the confidence interval
+ graphBoxPlot->setMedianConfidenceIntervalWidth(1);
+ graphBoxPlot->setDrawNotch(true);
+ graphBoxPlot->setRelativeNotchIndent(y0+0.5);
+
+ // ...
+ // ...
+
+ // 6. create a notched boxplot
+ // ...
+ // restyle as Tufte's box-less
+ graphBoxPlot->setDrawBox(false);
+
+ // ...
+ // ...
+
+ // 7. style box
+ // ...
+ // style box line&fill
+ graphBoxPlot->setLineColor(QColor("red"));
+ graphBoxPlot->setLineStyle(Qt::DotLine);
+ graphBoxPlot->setLineWidth(1);
+ graphBoxPlot->setFillColor(QColor("yellow"));
+
+ // ...
+ // ...
+
+ // 8. fancy style box
+ // ...
+ // style box fill
+ QLinearGradient linearGrad(QPointF(0, 0), QPointF(1, 1));
+ QColor c1(Qt::red);
+ QColor c2(Qt::yellow);
+ QColor c3(Qt::blue);
+ linearGrad.setColorAt(0, c1);
+ linearGrad.setColorAt(0.3, c2);
+ linearGrad.setColorAt(1, c3);
+ // use this CoordinateMode, so the gradient fills the whole graph area
+ linearGrad.setCoordinateMode(QGradient::ObjectBoundingMode);
+ graphBoxPlot->setFillGradient(linearGrad);
+
+ // ...
+ // ...
+
+ // 9. style median
+ // ...
+ // style box line
+ graphBoxPlot->setMedianLineColor(QColor("red"));
+ graphBoxPlot->setMedianLineWidth(3);
+
+ // ...
+ // ...
+
+ // 10. style whiskers&caps
+ // ...
+ // style box line
+ graphBoxPlot->setWhiskerLineColor(QColor("red"));
+ graphBoxPlot->setWhiskerLineStyle(Qt::DotLine);
+ graphBoxPlot->setWhiskerLineWidth(1);
+ graphBoxPlot->setWhiskerCapLineColor(QColor("blue"));
+ graphBoxPlot->setWhiskerCapLineStyle(Qt::SolidLine);
+ graphBoxPlot->setWhiskerCapLineWidth(4);
+ graphBoxPlot->setRelativeWhiskerWidth(0.9);
+```
+
+The result looks like this:
+
+![test_styledboxplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/test_styledboxplot.png)
diff --git a/examples/test_styledboxplot/test_styledboxplot.cpp b/examples/test_styledboxplot/test_styledboxplot.cpp
new file mode 100644
index 0000000000..1f2550faf6
--- /dev/null
+++ b/examples/test_styledboxplot/test_styledboxplot.cpp
@@ -0,0 +1,214 @@
+/** \example test_styledboxplot.cpp
+ * Shows how to style different aspects of boxplots.
+ *
+ * \ref JKQTPlotterBoxplotStyling
+ */
+
+#include
+#include "jkqtplotter/jkqtplotter.h"
+#include "jkqtplotter/jkqtpgraphsboxplot.h"
+#include "jkqtplotter/jkqtpgraphsgeometric.h"
+
+int main(int argc, char* argv[])
+{
+ QApplication app(argc, argv);
+
+ // 1. create a plotter window and get a pointer to the internal datastore (for convenience)
+ JKQTPlotter plot;
+ 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
+
+
+ JKQTPBoxplotVerticalElement* graphBoxPlot;
+ double x=1;
+ double dx=1;
+ double y0=11;
+
+ // 2. create a basic boxplot
+ plot.addGraph(graphBoxPlot=new JKQTPBoxplotVerticalElement(&plot));
+ plot.addGraph(new JKQTPGeoText(&plot, x-dx/2.0, y0+9, "\\textbf{\\begin{matrix}basic boxplot\\\\\"Turkey's style\"\\end{matrix}}", 8, QColor("black")));
+ graphBoxPlot->setPos(x);
+ graphBoxPlot->setMin(y0+1);
+ graphBoxPlot->setPercentile25(y0+2.5);
+ graphBoxPlot->setMedian(y0+4);
+ graphBoxPlot->setPercentile75(y0+5.5);
+ graphBoxPlot->setMax(y0+8);
+ // set color of all elements
+ graphBoxPlot->setBoxplotColor(QColor("black"),QColor("white"), plot.getPlotter());
+ x+=dx;
+
+ // 3. create a basic boxplot with mean as symbol
+ plot.addGraph(graphBoxPlot=new JKQTPBoxplotVerticalElement(&plot));
+ plot.addGraph(new JKQTPGeoText(&plot, x-dx/2.0, y0+9, "\\textbf{\\begin{matrix}basic boxplot\\\\ + mean symbol\\end{matrix}}", 8, QColor("black")));
+ graphBoxPlot->setPos(x);
+ graphBoxPlot->setMin(y0+1);
+ graphBoxPlot->setPercentile25(y0+2.5);
+ graphBoxPlot->setMedian(y0+4);
+ graphBoxPlot->setPercentile75(y0+5.5);
+ graphBoxPlot->setMax(y0+8);
+ // set color of all elements
+ graphBoxPlot->setBoxplotColor(QColor("black"),QColor("white"), plot.getPlotter());
+ // set mean value to show mean symbol
+ graphBoxPlot->setMean(y0+3.5);
+ graphBoxPlot->setDrawMean(true);
+ graphBoxPlot->setMeanMode(JKQTPGraphBoxplotStyleMixin::MeanAsSymbol);
+ graphBoxPlot->setMeanColor(QColor("darkgreen"));
+ graphBoxPlot->setMeanSymbolType(JKQTPFilledTriangle);
+ x+=dx;
+
+ // 4. create a basic boxplot with mean as line
+ plot.addGraph(graphBoxPlot=new JKQTPBoxplotVerticalElement(&plot));
+ plot.addGraph(new JKQTPGeoText(&plot, x-dx/2.0, y0+9, "\\textbf{\\begin{matrix}basic boxplot\\\\ + mean line\\end{matrix}}", 8, QColor("black")));
+ graphBoxPlot->setPos(x);
+ graphBoxPlot->setMin(y0+1);
+ graphBoxPlot->setPercentile25(y0+2.5);
+ graphBoxPlot->setMedian(y0+4);
+ graphBoxPlot->setPercentile75(y0+5.5);
+ graphBoxPlot->setMax(y0+8);
+ // set color of all elements
+ graphBoxPlot->setBoxplotColor(QColor("black"),QColor("white"), plot.getPlotter());
+ // set mean value to show mean symbol
+ graphBoxPlot->setMean(y0+3.5);
+ graphBoxPlot->setDrawMean(true);
+ graphBoxPlot->setMeanMode(JKQTPGraphBoxplotStyleMixin::MeanAsLine);
+ graphBoxPlot->setMeanColor(QColor("darkgreen"));
+ graphBoxPlot->setMeanLineStyle(Qt::DashLine);
+ graphBoxPlot->setMeanLineWidth(2);
+ x+=dx;
+
+ // 5. create a notched boxplot
+ plot.addGraph(graphBoxPlot=new JKQTPBoxplotVerticalElement(&plot));
+ plot.addGraph(new JKQTPGeoText(&plot, x-dx/2.0, y0+9, "\\textbf{notched boxplot}", 8, QColor("black")));
+ graphBoxPlot->setPos(x);
+ graphBoxPlot->setMin(y0+1);
+ graphBoxPlot->setPercentile25(y0+2.5);
+ graphBoxPlot->setMedian(y0+4);
+ graphBoxPlot->setPercentile75(y0+5.5);
+ graphBoxPlot->setMax(y0+8);
+ // set color of all elements
+ graphBoxPlot->setBoxplotColor(QColor("black"), QColor("white"), plot.getPlotter());
+ // for a notched plot, you need to set the confidence interval
+ graphBoxPlot->setMedianConfidenceIntervalWidth(1);
+ graphBoxPlot->setDrawNotch(true);
+ graphBoxPlot->setRelativeNotchIndent(0.5);
+ x+=dx;
+
+
+ // 6. create a notched boxplot
+ plot.addGraph(graphBoxPlot=new JKQTPBoxplotVerticalElement(&plot));
+ plot.addGraph(new JKQTPGeoText(&plot, x-dx/2.0, y0+9, "\\textbf{\\begin{matrix}basic boxplot\\\\\"Tufte's style\"\\end{matrix}}", 8, QColor("black")));
+ graphBoxPlot->setPos(x);
+ graphBoxPlot->setMin(y0+1);
+ graphBoxPlot->setPercentile25(y0+2.5);
+ graphBoxPlot->setMedian(y0+4);
+ graphBoxPlot->setPercentile75(y0+5.5);
+ graphBoxPlot->setMax(y0+8);
+ // set color of all elements
+ graphBoxPlot->setBoxplotColor(QColor("black"), QColor("white"), plot.getPlotter());
+ // restyle as Tufte's box-less
+ graphBoxPlot->setDrawBox(false);
+ x+=dx;
+
+
+
+ x=1;
+ y0=0;
+
+ // 7. style box
+ plot.addGraph(graphBoxPlot=new JKQTPBoxplotVerticalElement(&plot));
+ plot.addGraph(new JKQTPGeoText(&plot, x-dx/2.0, y0+9, "\\textbf{styled box}", 8, QColor("black")));
+ graphBoxPlot->setPos(x);
+ graphBoxPlot->setMin(y0+1);
+ graphBoxPlot->setPercentile25(y0+2.5);
+ graphBoxPlot->setMedian(y0+4);
+ graphBoxPlot->setPercentile75(y0+5.5);
+ graphBoxPlot->setMax(y0+8);
+ // set color of all elements
+ graphBoxPlot->setBoxplotColor(QColor("black"),QColor("white"), plot.getPlotter());
+ // style box line&fill
+ graphBoxPlot->setLineColor(QColor("red"));
+ graphBoxPlot->setLineStyle(Qt::DotLine);
+ graphBoxPlot->setLineWidth(1);
+ graphBoxPlot->setFillColor(QColor("yellow"));
+ x+=dx;
+
+ // 8. fancy style box
+ plot.addGraph(graphBoxPlot=new JKQTPBoxplotVerticalElement(&plot));
+ plot.addGraph(new JKQTPGeoText(&plot, x-dx/2.0, y0+9, "\\textbf{styled box}", 8, QColor("black")));
+ graphBoxPlot->setPos(x);
+ graphBoxPlot->setMin(y0+1);
+ graphBoxPlot->setPercentile25(y0+2.5);
+ graphBoxPlot->setMedian(y0+4);
+ graphBoxPlot->setPercentile75(y0+5.5);
+ graphBoxPlot->setMax(y0+8);
+ // set color of all elements
+ graphBoxPlot->setBoxplotColor(QColor("black"),QColor("white"), plot.getPlotter());
+ // style box fill
+ QLinearGradient linearGrad(QPointF(0, 0), QPointF(1, 1));
+ QColor c1(Qt::red);
+ QColor c2(Qt::yellow);
+ QColor c3(Qt::blue);
+ linearGrad.setColorAt(0, c1);
+ linearGrad.setColorAt(0.3, c2);
+ linearGrad.setColorAt(1, c3);
+ // use this CoordinateMode, so the gradient fills the whole graph area
+ linearGrad.setCoordinateMode(QGradient::ObjectBoundingMode);
+ graphBoxPlot->setFillGradient(linearGrad);
+ x+=dx;
+
+ // 9. style median
+ plot.addGraph(graphBoxPlot=new JKQTPBoxplotVerticalElement(&plot));
+ plot.addGraph(new JKQTPGeoText(&plot, x-dx/2.0, y0+9, "\\textbf{styled median}", 8, QColor("black")));
+ graphBoxPlot->setPos(x);
+ graphBoxPlot->setMin(y0+1);
+ graphBoxPlot->setPercentile25(y0+2.5);
+ graphBoxPlot->setMedian(y0+4);
+ graphBoxPlot->setPercentile75(y0+5.5);
+ graphBoxPlot->setMax(y0+8);
+ // set color of all elements
+ graphBoxPlot->setBoxplotColor(QColor("black"),QColor("white"), plot.getPlotter());
+ // style box line
+ graphBoxPlot->setMedianLineColor(QColor("red"));
+ graphBoxPlot->setMedianLineWidth(3);
+ x+=dx;
+
+
+ // 10. style whiskers&caps
+ plot.addGraph(graphBoxPlot=new JKQTPBoxplotVerticalElement(&plot));
+ plot.addGraph(new JKQTPGeoText(&plot, x-dx/2.0, y0+9, "\\textbf{styled whiskers}", 8, QColor("black")));
+ graphBoxPlot->setPos(x);
+ graphBoxPlot->setMin(y0+1);
+ graphBoxPlot->setPercentile25(y0+2.5);
+ graphBoxPlot->setMedian(y0+4);
+ graphBoxPlot->setPercentile75(y0+5.5);
+ graphBoxPlot->setMax(y0+8);
+ // set color of all elements
+ graphBoxPlot->setBoxplotColor(QColor("black"),QColor("white"), plot.getPlotter());
+ // style box line
+ graphBoxPlot->setWhiskerLineColor(QColor("red"));
+ graphBoxPlot->setWhiskerLineStyle(Qt::DotLine);
+ graphBoxPlot->setWhiskerLineWidth(1);
+ graphBoxPlot->setWhiskerCapLineColor(QColor("blue"));
+ graphBoxPlot->setWhiskerCapLineStyle(Qt::SolidLine);
+ graphBoxPlot->setWhiskerCapLineWidth(4);
+ graphBoxPlot->setRelativeWhiskerWidth(0.9);
+ x+=dx;
+
+
+
+
+
+ // 11. autoscale the plot so the graph is contained
+ plot.setXY(0.5,5.5,0, 21);
+
+ // 12. style plot
+ plot.getPlotter()->setShowKey(false);
+ plot.getPlotter()->setGrid(false);
+
+ // 13. show plotter and make it a decent size
+ plot.show();
+ plot.resize(600,500);
+
+ return app.exec();
+}
diff --git a/examples/test_styledboxplot/test_styledboxplot.pro b/examples/test_styledboxplot/test_styledboxplot.pro
new file mode 100644
index 0000000000..8708da16f4
--- /dev/null
+++ b/examples/test_styledboxplot/test_styledboxplot.pro
@@ -0,0 +1,25 @@
+# source code for this simple demo
+SOURCES = test_styledboxplot.cpp
+
+# configure Qt
+CONFIG += link_prl qt
+QT += core gui xml svg
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
+
+# output executable name
+TARGET = test_styledboxplot
+
+# include JKQTPlotter source code
+DEPENDPATH += ../../lib ../../staticlib/jkqtplotterlib
+INCLUDEPATH += ../../lib
+CONFIG (debug, debug|release) {
+ LIBS += -L../../staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug
+} else {
+ LIBS += -L../../staticlib/jkqtplotterlib/release -ljkqtplotterlib
+}
+message("LIBS = $$LIBS")
+
+
+
+
+
diff --git a/examples/test_styledboxplot/test_styledboxplot_and_lib.pro b/examples/test_styledboxplot/test_styledboxplot_and_lib.pro
new file mode 100644
index 0000000000..35564d409b
--- /dev/null
+++ b/examples/test_styledboxplot/test_styledboxplot_and_lib.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+
+SUBDIRS += jkqtplotterlib test_styledboxplot
+
+jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro
+
+test_styledboxplot.file=$$PWD/test_styledboxplot.pro
+test_styledboxplot.depends = jkqtplotterlib
diff --git a/lib/jkqtplotter.pri b/lib/jkqtplotter.pri
index 61a506e409..3a61b2637e 100644
--- a/lib/jkqtplotter.pri
+++ b/lib/jkqtplotter.pri
@@ -20,6 +20,7 @@ HEADERS += \
$$PWD/jkqtplotter/jkqtpgraphsbaseerrors.h \
$$PWD/jkqtplotter/jkqtpgraphsbasestylingmixins.h \
$$PWD/jkqtplotter/jkqtpgraphsboxplot.h \
+ $$PWD/jkqtplotter/jkqtpgraphsboxplotstylingmixins.h \
$$PWD/jkqtplotter/jkqtpgraphsevaluatedfunction.h \
$$PWD/jkqtplotter/jkqtpgraphsfilledcurve.h \
$$PWD/jkqtplotter/jkqtpgraphsgeometric.h \
@@ -65,6 +66,7 @@ SOURCES += \
$$PWD/jkqtplotter/jkqtpgraphsbaseerrors.cpp \
$$PWD/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp \
$$PWD/jkqtplotter/jkqtpgraphsboxplot.cpp \
+ $$PWD/jkqtplotter/jkqtpgraphsboxplotstylingmixins.cpp \
$$PWD/jkqtplotter/jkqtpgraphsevaluatedfunction.cpp \
$$PWD/jkqtplotter/jkqtpgraphsfilledcurve.cpp \
$$PWD/jkqtplotter/jkqtpgraphsgeometric.cpp \
diff --git a/lib/jkqtplotter/jkqtpdatastorage.cpp b/lib/jkqtplotter/jkqtpdatastorage.cpp
index 3dd932b6f6..6dfcdc3f74 100644
--- a/lib/jkqtplotter/jkqtpdatastorage.cpp
+++ b/lib/jkqtplotter/jkqtpdatastorage.cpp
@@ -336,7 +336,7 @@ int JKQTPDatastore::getColumnNum(const QString& name) {
QMapIterator it(columns);
while (it.hasNext()) {
it.next();
- if (it.value().getName()==name) return it.key();
+ if (it.value().getName()==name) return static_cast(it.key());
}
return -1;
}
@@ -347,21 +347,22 @@ int JKQTPDatastore::ensureColumnNum(const QString& name) {
QMapIterator it(columns);
while (it.hasNext()) {
it.next();
- if (it.value().getName()==name) return it.key();
+ if (it.value().getName()==name) return static_cast(it.key());
}
- return addColumn(0, name);
+ return static_cast(addColumn(0, name));
}
////////////////////////////////////////////////////////////////////////////////////////////////
JKQTPColumn JKQTPDatastore::getColumn(size_t i) const
{
- return columns.value(i);
+ return columns.value(i, JKQTPColumn());
}
////////////////////////////////////////////////////////////////////////////////////////////////
JKQTPColumn JKQTPDatastore::getColumn(int i) const
{
- return columns.value(i);
+ if (i<0) return JKQTPColumn();
+ return getColumn(static_cast(i));
}
////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/lib/jkqtplotter/jkqtpdatastorage.h b/lib/jkqtplotter/jkqtpdatastorage.h
index ac2fbf6304..0257344c15 100644
--- a/lib/jkqtplotter/jkqtpdatastorage.h
+++ b/lib/jkqtplotter/jkqtpdatastorage.h
@@ -197,6 +197,10 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{
/** \brief returns the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */
inline double get(int column, size_t row) const ;
+ /** \brief returns the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */
+ inline double get(int column, int row) const ;
+ /** \brief returns the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */
+ inline double get(size_t column, int row) const ;
/** \brief gets the index of the datapoint with the nearest, but lower value in the column (in a given inclusive row range [start ... end] values of -1 for the ranges are "wildcards", i.e. start/end of column)*/
int getNextLowerIndex(size_t column, size_t row, int start, int end) const;
/** \brief gets the index of the datapoint with the nearest, but lower value in the column */
@@ -876,16 +880,16 @@ inline void JKQTPColumn::incValue(size_t n, double increment){
////////////////////////////////////////////////////////////////////////////////////////////////
inline double JKQTPColumn::getValue(size_t n) const {
- if (!datastore) return nan("");
- if (!datastore->getItem(datastoreItem)) return nan("");
+ if (!datastore) return JKQTP_NAN;
+ if (!datastore->getItem(datastoreItem)) return JKQTP_NAN;
return datastore->getItem(datastoreItem)->get(datastoreOffset, n);
}
////////////////////////////////////////////////////////////////////////////////////////////////
inline double JKQTPColumn::getValue(int n) const {
- if (!datastore) return nan("");
- if (!datastore->getItem(datastoreItem)) return nan("");
- if (n<0) return nan("");
+ if (!datastore) return JKQTP_NAN;
+ if (!datastore->getItem(datastoreItem)) return JKQTP_NAN;
+ if (n<0) return JKQTP_NAN;
return datastore->getItem(datastoreItem)->get(datastoreOffset, static_cast(n));
}
@@ -896,6 +900,21 @@ inline double JKQTPDatastore::get(size_t column, size_t row) const {
////////////////////////////////////////////////////////////////////////////////////////////////
inline double JKQTPDatastore::get(int column, size_t row) const {
+ if (column<0) return JKQTP_NAN;
+ return get(static_cast(column), static_cast(row));
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+inline double JKQTPDatastore::get(int column, int row) const {
+ if (column<0) return JKQTP_NAN;
+ if (row<0) return JKQTP_NAN;
+ return get(static_cast(column), static_cast(row));
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+inline double JKQTPDatastore::get(size_t column, int row) const {
+ if (row<0) return JKQTP_NAN;
return get(static_cast(column), static_cast(row));
}
diff --git a/lib/jkqtplotter/jkqtpgraphsbase.cpp b/lib/jkqtplotter/jkqtpgraphsbase.cpp
index dcddf362ab..d1ec5e95ba 100644
--- a/lib/jkqtplotter/jkqtpgraphsbase.cpp
+++ b/lib/jkqtplotter/jkqtpgraphsbase.cpp
@@ -197,11 +197,11 @@ QString JKQTPPlotElement::formatHitTestDefaultLabel(double x, double y, int inde
double JKQTPPlotElement::hitTest(const QPointF & posSystem, QPointF* closestSpotSystem, QString* label, HitTestMode mode) const
{
- if (parent==nullptr) return nan("");
+ if (parent==nullptr) return JKQTP_NAN;
int closest=-1;
- double closedist=nan("");
- double closedistsec=nan("");
+ double closedist=JKQTP_NAN;
+ double closedistsec=JKQTP_NAN;
QPointF closestPos;
QPointF posF=transform(posSystem);
for (int i=0; igetDatastore();
int imin=0;
int imax=0;
- if (!getIndexRange(imin, imax)) return nan("");
+ if (!getIndexRange(imin, imax)) return JKQTP_NAN;
int closest=-1;
- double closedist=nan("");
- double closedistsec=nan("");
+ double closedist=JKQTP_NAN;
+ double closedistsec=JKQTP_NAN;
QPointF closestPos;
QPointF posF=transform(posSystem);
for (int i=imin; iQPainter to draw to
\param x x-coordinate of the symbol center
\param y y-coordinate of the symbol center
@@ -228,6 +229,7 @@ class JKQTP_LIB_EXPORT JKQTPGraphSymbolStyleMixin {
void plotStyledSymbol(JKQTBasePlotter* parent, JKQTPEnhancedPainter& painter, double x, double y) const;
/*! \brief plot a symbol at location x,y (in painter coordinates), using the current style
+ \param parent parent JKQTBasePlotter of the graph that uses this mix-in (used e.g. for line-width transformation)
\param painter the QPainter to draw to
\param x x-coordinate of the symbol center
\param y y-coordinate of the symbol center
@@ -236,6 +238,7 @@ class JKQTP_LIB_EXPORT JKQTPGraphSymbolStyleMixin {
void plotStyledSymbol(JKQTBasePlotter* parent, JKQTPEnhancedPainter& painter, double x, double y, double symbolSize) const;
/*! \brief plot a symbol at location x,y (in painter coordinates), using the current style
+ \param parent parent JKQTBasePlotter of the graph that uses this mix-in (used e.g. for line-width transformation)
\param painter the QPainter to draw to
\param x x-coordinate of the symbol center
\param y y-coordinate of the symbol center
@@ -245,6 +248,7 @@ class JKQTP_LIB_EXPORT JKQTPGraphSymbolStyleMixin {
void plotStyledSymbol(JKQTBasePlotter* parent, JKQTPEnhancedPainter& painter, double x, double y, JKQTPGraphSymbols type) const;
/*! \brief plot a symbol at location x,y (in painter coordinates), using the current style
+ \param parent parent JKQTBasePlotter of the graph that uses this mix-in (used e.g. for line-width transformation)
\param painter the QPainter to draw to
\param x x-coordinate of the symbol center
\param y y-coordinate of the symbol center
diff --git a/lib/jkqtplotter/jkqtpgraphsboxplot.cpp b/lib/jkqtplotter/jkqtpgraphsboxplot.cpp
index 36214c3729..e720155900 100644
--- a/lib/jkqtplotter/jkqtpgraphsboxplot.cpp
+++ b/lib/jkqtplotter/jkqtpgraphsboxplot.cpp
@@ -32,258 +32,12 @@
-JKQTPGraphBoxplotStyleMixin::JKQTPGraphBoxplotStyleMixin()
-{
-
- boxWidth=0.4;
-
- m_whiskerLinePen=QPen(getLineColor(), getLineWidth());
- whiskerLineWidth=getLineWidth();
- m_medianLinePen=QPen(getLineColor(), getLineWidth());
- medianLineWidth=getLineWidth();
-
-}
-
-
-void JKQTPGraphBoxplotStyleMixin::initBoxplotStyle(JKQTBasePlotter *parent, int &parentPlotStyle)
-{
- initFillStyle(parent, parentPlotStyle);
- initLineStyle(parent, parentPlotStyle);
- initSymbolStyle(parent, parentPlotStyle);
- if (parent && parentPlotStyle>=0) { // get style settings from parent object
- parentPlotStyle=parent->getNextStyle();
- m_whiskerLinePen.setColor(parent->getPlotStyle(parentPlotStyle).color());
- m_whiskerLinePen.setStyle(parent->getPlotStyle(parentPlotStyle).style());
- whiskerLineWidth=parent->getPlotStyle(parentPlotStyle).widthF();
- m_medianLinePen.setColor(parent->getPlotStyle(parentPlotStyle).color());
- m_medianLinePen.setStyle(parent->getPlotStyle(parentPlotStyle).style());
- medianLineWidth=parent->getPlotStyle(parentPlotStyle).widthF();
- }
-
- setWhiskerLineColor(getLineColor());
- setMedianLineColor(getLineColor());
-}
-
-void JKQTPGraphBoxplotStyleMixin::setBoxplotColor(QColor c, JKQTBasePlotter *parent)
-{
- setLineColor(c);
- setFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphFillColorDerivationMode, c));
- c.setAlphaF(0.5);
- setHighlightingLineColor(c);
- setSymbolColor(c);
- setSymbolFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphFillColorDerivationMode, c));
- setWhiskerLineColor(getLineColor());
- setMedianLineColor(getLineColor());
-}
-
-void JKQTPGraphBoxplotStyleMixin::setBoxWidth(double __value)
-{
- this->boxWidth = __value;
-}
-
-double JKQTPGraphBoxplotStyleMixin::getBoxWidth() const
-{
- return this->boxWidth;
-}
-
-void JKQTPGraphBoxplotStyleMixin::setWhiskerLineStyle(Qt::PenStyle __value)
-{
- this->m_whiskerLinePen.setStyle(__value);
-}
-
-Qt::PenStyle JKQTPGraphBoxplotStyleMixin::getWhiskerLineStyle() const
-{
- return this->m_whiskerLinePen.style();
-}
-
-
-void JKQTPGraphBoxplotStyleMixin::setWhiskerLineWidth(double __value)
-{
- whiskerLineWidth=__value;
-}
-
-double JKQTPGraphBoxplotStyleMixin::getWhiskerLineWidth() const
-{
- return whiskerLineWidth;
-}
-
-void JKQTPGraphBoxplotStyleMixin::setWhiskerLineColor(QColor __value)
-{
- m_whiskerLinePen.setColor(__value);
-}
-
-QColor JKQTPGraphBoxplotStyleMixin::getWhiskerLineColor() const
-{
- return m_whiskerLinePen.color();
-}
-
-void JKQTPGraphBoxplotStyleMixin::setWhiskerLineDashOffset(qreal offset)
-{
- m_whiskerLinePen.setDashOffset(offset);
-}
-
-qreal JKQTPGraphBoxplotStyleMixin::getWhiskerLineDashOffset() const
-{
- return m_whiskerLinePen.dashOffset();
-}
-
-void JKQTPGraphBoxplotStyleMixin::setWhiskerLineDashPattern(const QVector &pattern)
-{
- m_whiskerLinePen.setDashPattern(pattern);
- m_whiskerLinePen.setStyle(Qt::CustomDashLine);
-}
-
-QVector JKQTPGraphBoxplotStyleMixin::getWhiskerLineDashPattern() const
-{
- return m_whiskerLinePen.dashPattern();
-}
-
-void JKQTPGraphBoxplotStyleMixin::setWhiskerLineJoinStyle(Qt::PenJoinStyle style)
-{
- m_whiskerLinePen.setJoinStyle(style);
-}
-
-Qt::PenJoinStyle JKQTPGraphBoxplotStyleMixin::getWhiskerLineJoinStyle() const
-{
- return m_whiskerLinePen.joinStyle();
-}
-
-void JKQTPGraphBoxplotStyleMixin::setWhiskerLineCapStyle(Qt::PenCapStyle style)
-{
- m_whiskerLinePen.setCapStyle(style);
-}
-
-Qt::PenCapStyle JKQTPGraphBoxplotStyleMixin::getWhiskerLineCapStyle() const
-{
- return m_whiskerLinePen.capStyle();
-}
-
-void JKQTPGraphBoxplotStyleMixin::setWhiskerLineBrush(const QBrush &style)
-{
- m_whiskerLinePen.setBrush(style);
-}
-
-QBrush JKQTPGraphBoxplotStyleMixin::getWhiskerLineBrush() const
-{
- return m_whiskerLinePen.brush();
-}
-
-QPen JKQTPGraphBoxplotStyleMixin::getWhiskerPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const
-{
- QPen pw=m_whiskerLinePen;
- pw.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*whiskerLineWidth)));
- pw.setJoinStyle(Qt::MiterJoin);
- return pw;
-}
-
-
-
-
-
-void JKQTPGraphBoxplotStyleMixin::setMedianLineStyle(Qt::PenStyle __value)
-{
- this->m_medianLinePen.setStyle(__value);
-}
-
-Qt::PenStyle JKQTPGraphBoxplotStyleMixin::getMedianLineStyle() const
-{
- return this->m_medianLinePen.style();
-}
-
-
-void JKQTPGraphBoxplotStyleMixin::setMedianLineWidth(double __value)
-{
- medianLineWidth=__value;
-}
-
-double JKQTPGraphBoxplotStyleMixin::getMedianLineWidth() const
-{
- return medianLineWidth;
-}
-
-void JKQTPGraphBoxplotStyleMixin::setMedianLineColor(QColor __value)
-{
- m_medianLinePen.setColor(__value);
-}
-
-QColor JKQTPGraphBoxplotStyleMixin::getMedianLineColor() const
-{
- return m_medianLinePen.color();
-}
-
-void JKQTPGraphBoxplotStyleMixin::setMedianLineDashOffset(qreal offset)
-{
- m_medianLinePen.setDashOffset(offset);
-}
-
-qreal JKQTPGraphBoxplotStyleMixin::getMedianLineDashOffset() const
-{
- return m_medianLinePen.dashOffset();
-}
-
-void JKQTPGraphBoxplotStyleMixin::setMedianLineDashPattern(const QVector &pattern)
-{
- m_medianLinePen.setDashPattern(pattern);
- m_medianLinePen.setStyle(Qt::CustomDashLine);
-}
-
-QVector JKQTPGraphBoxplotStyleMixin::getMedianLineDashPattern() const
-{
- return m_medianLinePen.dashPattern();
-}
-
-void JKQTPGraphBoxplotStyleMixin::setMedianLineJoinStyle(Qt::PenJoinStyle style)
-{
- m_medianLinePen.setJoinStyle(style);
-}
-
-Qt::PenJoinStyle JKQTPGraphBoxplotStyleMixin::getMedianLineJoinStyle() const
-{
- return m_medianLinePen.joinStyle();
-}
-
-void JKQTPGraphBoxplotStyleMixin::setMedianLineCapStyle(Qt::PenCapStyle style)
-{
- m_medianLinePen.setCapStyle(style);
-}
-
-Qt::PenCapStyle JKQTPGraphBoxplotStyleMixin::getMedianLineCapStyle() const
-{
- return m_medianLinePen.capStyle();
-}
-
-void JKQTPGraphBoxplotStyleMixin::setMedianLineBrush(const QBrush &style)
-{
- m_medianLinePen.setBrush(style);
-}
-
-QBrush JKQTPGraphBoxplotStyleMixin::getMedianLineBrush() const
-{
- return m_medianLinePen.brush();
-}
-
-QPen JKQTPGraphBoxplotStyleMixin::getMedianPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const
-{
- QPen pw=m_medianLinePen;
- pw.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*medianLineWidth)));
- pw.setJoinStyle(Qt::MiterJoin);
- return pw;
-}
-
-
-
-
-
-
-
-
-
-
-
JKQTPBoxplotVerticalGraph::JKQTPBoxplotVerticalGraph(JKQTBasePlotter* parent):
JKQTPGraph(parent)
{
+ boxWidthRelative=0.4;
+ useRelativeBoxWidth=true;
posColumn=-1;
medianColumn=-1;
meanColumn=-1;
@@ -291,6 +45,7 @@ JKQTPBoxplotVerticalGraph::JKQTPBoxplotVerticalGraph(JKQTBasePlotter* parent):
maxColumn=-1;
percentile25Column=-1;
percentile75Column=-1;
+ medianConfidenceColumn=-1;
sortData=Unsorted;
@@ -316,14 +71,7 @@ void JKQTPBoxplotVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
drawErrorsBefore(painter);
-
- QPen p=getLinePenForRects(painter, parent);
- QPen pw=getWhiskerPen(painter, parent);
- QPen pm=getMedianPen(painter, parent);
- QPen np(Qt::NoPen);
- QBrush b=getFillBrush(painter, parent);
-
- int imax=datastore->getColumn(posColumn).getRows();
+ int imax=static_cast(datastore->getColumn(static_cast(posColumn)).getRows());
int imin=0;
if (imaxget(posColumn,i-1));
- double xv=transformX(datastore->get(posColumn,i));
+ int i=qBound(imin+1, getDataIndex(iii), imax);
+ double xv0=transformX(datastore->get(static_cast(posColumn),static_cast(i-1)));
+ double xv=transformX(datastore->get(static_cast(posColumn),static_cast(i)));
if (posColumn>=0 && JKQTPIsOKFloat(xv) && JKQTPIsOKFloat(xv0)) {
if (bwfirst) {
boxwidth_real=fabs(xv-xv0);
@@ -355,6 +103,7 @@ void JKQTPBoxplotVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
}
}
}
+
// 2. plot:
{
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
@@ -365,11 +114,9 @@ void JKQTPBoxplotVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
const double minv=datastore->get(minColumn,static_cast(i));
const double maxv=datastore->get(maxColumn,static_cast(i));
const double medianv=datastore->get(medianColumn,static_cast(i));
+ const double medConf=datastore->get(medianConfidenceColumn,static_cast(i));
const double meanv=datastore->get(meanColumn,static_cast(i));
- QVector lines_p, lines_pw, lines_m;
-
- //std::cout<<"(xv, yv) = ( "<=0 && JKQTPIsOKFloat(xv) ) {
// collect single-value labels for hitTest()-data at the bottom of this loop!
@@ -379,72 +126,33 @@ void JKQTPBoxplotVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
labelValues<=0 && JKQTPIsOKFloat(minv)) { labelNames<<"\\min"; labelValues<=0 && JKQTPIsOKFloat(p25v)) { labelNames<<"q_{25}"; labelValues<=0 && JKQTPIsOKFloat(medianv)) { labelNames<<"\\median"; labelValues<=0 && JKQTPIsOKFloat(medianv)) {
+ if (medianConfidenceColumn>=0 && JKQTPIsOKFloat(medConf)) {
+ labelNames<<"\\median"; labelValues<<(QString::fromStdString(jkqtp_floattolatexstr(medianv, 3))+"\\:{\\pm}\\:"+QString::fromStdString(jkqtp_floattolatexstr(medConf, 3))); labMedian=labelValues.size()-1;
+ } else {
+ labelNames<<"\\median"; labelValues<=0 && JKQTPIsOKFloat(meanv)) { labelNames<<"\\mu"; labelValues<=0 && JKQTPIsOKFloat(p75v)) { labelNames<<"q_{75}"; labelValues<=0 && JKQTPIsOKFloat(maxv)) { labelNames<<"\\max"; labelValues<get(posColumn,static_cast(i+1)));
- else if (i-1>=0) xn=transformX(datastore->get(posColumn,static_cast(i-1)));
- else xn=x+1;
-
- double w=((boxwidth_real>0)?boxwidth_real:(fabs(xn-x)))*getBoxWidth();
- double minstop=p25;
- double maxstop=p75;
- if (percentile25Column<0 && medianColumn>=0) minstop=median;
- else if (percentile25Column<0 && meanColumn>=0) minstop=mean;
- else if (percentile25Column<0 && maxColumn>=0) minstop=max;
- if (percentile75Column<0 && medianColumn>=0) maxstop=median;
- else if (percentile75Column<0 && meanColumn>=0) maxstop=mean;
- else if (percentile75Column<0 && minColumn>=0) maxstop=min;
+ double w=(useRelativeBoxWidth && boxwidth_real>0)?(boxwidth_real*getBoxWidthRelative()):parent->pt2px(painter,getBoxWidthAbsolute());
double xma=x+w/2.0;
double xmi=x-w/2.0;
- double xma4=x+w/4.0;
- double xmi4=x-w/4.0;
- if (imax<=0) {
- xma=transformX(xv+getBoxWidth()/2.0);
- xmi=transformX(xv-getBoxWidth()/2.0);
- xma4=transformX(xv+getBoxWidth()/4.0);
- xmi4=transformX(xv-getBoxWidth()/4.0);
- }
-
- if (minColumn>=0) {
- lines_pw.append(QLineF(xmi4, min, xma4, min));
- lines_pw.append(QLineF(x, min, x, minstop));
- }
- if (maxColumn>=0) {
- lines_pw.append(QLineF(xmi4, max, xma4, max));
- lines_pw.append(QLineF(x, max, x, maxstop));
- }
-
- if (percentile25Column>=0 && percentile75Column>=0) painter.drawRect(QRectF(xmi, p75, fabs(xma-xmi), fabs(p75-p25)));
- if (medianColumn>=0) lines_m.append(QLineF(xmi+p.widthF()/2.0, median, xma-p.widthF()/2.0, median));
- if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) {
- plotStyledSymbol(parent, painter,x,mean);
- }
-
-
- painter.setPen(p);
- if (lines_p.size()>0) painter.drawLines(lines_p);
- painter.setPen(pw);
- if (lines_pw.size()>0) painter.drawLines(lines_pw);
- painter.setPen(pm);
- if (lines_m.size()>0) painter.drawLines(lines_m);
+ plotVerticalBoxplot(parent, painter, x, xmi, xma, min, p25, median, p75, max, mean, medianu, mediano);
// add hit-test graph points
@@ -505,7 +213,7 @@ bool JKQTPBoxplotVerticalGraph::getXMinMax(double& minx, double& maxx, double& s
JKQTPDatastore* datastore=parent->getDatastore();
int imin=0;
- int imax=datastore->getColumn(posColumn).getRows();
+ int imax=static_cast(datastore->getColumn(static_cast(posColumn)).getRows());
if (imaxget(posColumn,i);
+ double xv=datastore->get(posColumn,static_cast(i));
if (JKQTPIsOKFloat(xv)) {
double xn=xv+1;
if (i+1get(posColumn,i+1);
else if (i-1>=0) xn=datastore->get(posColumn,i-1);
else xn=xv+1;
double delta=fabs(xn-xv);
- double w=delta*getBoxWidth();
+ double w=delta*getBoxWidthRelative();
double xma=xv+w;
double xmi=xv-w;
if (start || xma>maxx) maxx=xma;
@@ -603,7 +311,7 @@ JKQTPBoxplotVerticalGraph::DataSortOrder JKQTPBoxplotVerticalGraph::getDataSortO
}
void JKQTPBoxplotVerticalGraph::setDataSortOrder(int __value) {
- sortData=(DataSortOrder)__value;
+ sortData=static_cast(__value);
if (__value>0) sortData=Sorted;
}
@@ -705,44 +413,39 @@ void JKQTPBoxplotVerticalGraph::setPercentile75Column(size_t __value) {
this->percentile75Column = static_cast(__value);
}
+int JKQTPBoxplotVerticalGraph::getMedianConfidenceColumn() const
+{
+ return medianConfidenceColumn;
+}
+
+void JKQTPBoxplotVerticalGraph::setMedianConfidenceColumn(size_t __value)
+{
+ medianConfidenceColumn=static_cast(__value);
+}
+
+void JKQTPBoxplotVerticalGraph::setBoxWidthRelative(double __value)
+{
+ this->boxWidthRelative = __value;
+}
+
+double JKQTPBoxplotVerticalGraph::getBoxWidthRelative() const
+{
+ return this->boxWidthRelative;
+}
+
+void JKQTPBoxplotVerticalGraph::setUseRelativeBoxWidth(bool __value)
+{
+ useRelativeBoxWidth=__value;
+}
+
+bool JKQTPBoxplotVerticalGraph::getUseRelativeBoxWidth() const
+{
+ return useRelativeBoxWidth;
+}
+
void JKQTPBoxplotVerticalGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) {
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- QPen p=getLinePenForRects(painter, parent);
- QPen pw=getWhiskerPen(painter, parent);
- QPen pm=getMedianPen(painter, parent);
- QPen np(Qt::NoPen);
- QBrush b=getFillBrush(painter, parent);
-
- p.setWidthF(qMin(1.0, p.widthF()));
- pw.setWidthF(qMin(1.0, pw.widthF()));
- pm.setWidthF(qMin(1.0, pm.widthF()));
-
- double x=rect.left()+rect.width()/2.0;
- double xma=x+rect.width()/2.5;
- double xmi=x-rect.width()/2.5;
- double min=rect.bottom();
- double max=rect.top();
- double median=max+rect.height()/2.0;
- double w=rect.width()/1.8;
- double p25=max+0.75*rect.height();
- double p75=max+0.25*rect.height();
-
- painter.setPen(p);
- {
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- painter.setBrush(b);
- painter.drawRect(QRectF(xmi, p75, fabs(xma-xmi), fabs(p75-p25)));
- }
-
- painter.setPen(pm);
- painter.drawLine(QLineF(xmi, median, xma, median));
- painter.setPen(pw);
- painter.drawLine(QLineF(x-w/4.0, max, x+w/4.0, max));
- painter.drawLine(QLineF(x-w/4.0, min, x+w/4.0, min));
- painter.drawLine(QLineF(x, max, x, p75));
- painter.drawLine(QLineF(x, min, x, p25));
-
+ plotVerticalKeyMarker(parent, painter, rect);
}
QColor JKQTPBoxplotVerticalGraph::getKeyLabelColor() const {
@@ -758,41 +461,7 @@ void JKQTPBoxplotVerticalGraph::setColor(QColor c)
void JKQTPBoxplotHorizontalGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) {
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- QPen p=getLinePenForRects(painter, parent);
- QPen pw=getWhiskerPen(painter, parent);
- QPen pm=getMedianPen(painter, parent);
- QPen np(Qt::NoPen);
- QBrush b=getFillBrush(painter, parent);
- p.setWidthF(qMin(1.0, p.widthF()));
- pw.setWidthF(qMin(1.0, pw.widthF()));
- pm.setWidthF(qMin(1.0, pm.widthF()));
-
-
- double y=rect.top()+rect.height()/2.0;
- double yma=y+rect.height()/2.5;
- double ymi=y-rect.height()/2.5;
- double min=rect.left();
- double max=rect.right();
- double median=max-rect.width()/2.0;
- double w=rect.height()/1.8;
- double p25=min+0.75*rect.width();
- double p75=min+0.25*rect.width();
-
- painter.setPen(p);
- {
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- painter.setBrush(b);
- painter.drawRect(QRectF(p75, ymi, fabs(p75-p25), fabs(yma-ymi)));
- }
-
- painter.setPen(pm);
- painter.drawLine(QLineF(median, ymi, median, yma));
- painter.setPen(pw);
- painter.drawLine(QLineF(max, y-w/4.0, max, y+w/4.0));
- painter.drawLine(QLineF(min, y-w/4.0, min, y+w/4.0));
- painter.drawLine(QLineF(max, y, p75, y));
- painter.drawLine(QLineF(min, y, p25, y));
+ plotHorizontalKeyMarker(parent, painter, rect);
}
@@ -857,7 +526,7 @@ bool JKQTPBoxplotHorizontalGraph::getYMinMax(double& minx, double& maxx, double&
JKQTPDatastore* datastore=parent->getDatastore();
int imin=0;
- int imax=datastore->getColumn(posColumn).getRows();
+ int imax=static_cast(datastore->getColumn(static_cast(posColumn)).getRows());
if (imaxget(posColumn,i);
+ double xv=datastore->get(posColumn,static_cast(i));
double xn=xv+1;
if (i+1get(posColumn,i+1);
else if (i-1>=0) xn=datastore->get(posColumn,i-1);
else xn=xv+1;
double delta=fabs(xn-xv);
- double w=delta*getBoxWidth();
+ double w=delta*getBoxWidthRelative();
double xma=xv+w;
double xmi=xv-w;
if (JKQTPIsOKFloat(xma) && JKQTPIsOKFloat(xmi) ) {
@@ -908,14 +577,8 @@ void JKQTPBoxplotHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
drawErrorsBefore(painter);
- QPen p=getLinePenForRects(painter, parent);
- QPen pw=getWhiskerPen(painter, parent);
- QPen pm=getMedianPen(painter, parent);
- QPen np(Qt::NoPen);
- QBrush b=getFillBrush(painter, parent);
-
- int imax=datastore->getColumn(posColumn).getRows();
+ int imax=static_cast(datastore->getColumn(static_cast(posColumn)).getRows());
int imin=0;
if (imaxget(maxColumn,static_cast(i));
const double medianv=datastore->get(medianColumn,static_cast(i));
const double meanv=datastore->get(meanColumn,static_cast(i));
+ const double medConf=datastore->get(medianConfidenceColumn,static_cast(i));
- QVector lines_p, lines_pw, lines_m;
- //std::cout<<"(xv, yv) = ( "<=0 && JKQTPIsOKFloat(yv) ) {
@@ -968,16 +630,18 @@ void JKQTPBoxplotHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
labelValues<=0 && JKQTPIsOKFloat(minv)) { labelNames<<"\\min"; labelValues<=0 && JKQTPIsOKFloat(p25v)) { labelNames<<"q_{25}"; labelValues<=0 && JKQTPIsOKFloat(medianv)) { labelNames<<"\\median"; labelValues<=0 && JKQTPIsOKFloat(medianv)) {
+ if (medianConfidenceColumn>=0 && JKQTPIsOKFloat(medConf)) {
+ labelNames<<"\\median"; labelValues<<(QString::fromStdString(jkqtp_floattolatexstr(medianv, 3))+"\\:{\\pm}\\:"+QString::fromStdString(jkqtp_floattolatexstr(medConf, 3))); labMedian=labelValues.size()-1;
+ } else {
+ labelNames<<"\\median"; labelValues<=0 && JKQTPIsOKFloat(meanv)) { labelNames<<"\\mu"; labelValues<=0 && JKQTPIsOKFloat(p75v)) { labelNames<<"q_{75}"; labelValues<=0 && JKQTPIsOKFloat(maxv)) { labelNames<<"\\max"; labelValues<=0) minstop=median;
- else if (percentile25Column<0 && maxColumn>=0) minstop=max;
- else if (percentile25Column<0 && meanColumn>=0) minstop=mean;
- if (percentile75Column<0 && medianColumn>=0) maxstop=median;
- else if (percentile75Column<0 && minColumn>=0) maxstop=min;
- else if (percentile75Column<0 && meanColumn>=0) maxstop=mean;
+ double w=(useRelativeBoxWidth && boxwidth_real>0)?(boxwidth_real*getBoxWidthRelative()):parent->pt2px(painter,getBoxWidthAbsolute());
+ double yma=y+w/2.0;
+ double ymi=y-w/2.0;
- double yn=y+1;
- if (i+1get(posColumn,static_cast(i+1)));
- else if (i-1>=0) yn=transformY(datastore->get(posColumn,static_cast(i-1)));
- else yn=y+1;
- double delta=fabs(yn-y);
- double w=((boxwidth_real>0)?boxwidth_real:(delta))*getBoxWidth();
- double yma=y-w/2.0;
- double ymi=y+w/2.0;
- double yma4=y+w/4.0;
- double ymi4=y-w/4.0;
- if (imax<=1) {
- ymi=transformY(yv+getBoxWidth()/2.0);
- yma=transformY(yv-getBoxWidth()/2.0);
- yma4=transformY(yv+getBoxWidth()/4.0);
- ymi4=transformY(yv-getBoxWidth()/4.0);
- }
- if (minColumn>=0) {
- lines_pw.append(QLineF(min, ymi4, min, yma4));
- lines_pw.append(QLineF(min, y, minstop, y));
- }
- if (maxColumn>=0) {
- lines_pw.append(QLineF(max, ymi4, max, yma4));
- lines_pw.append(QLineF(max, y, maxstop, y));
- }
- if (percentile25Column>=0 && percentile75Column>=0) painter.drawRect(QRectF(p25, qMin(yma,ymi), fabs(p75-p25), fabs(yma-ymi)));
- if (medianColumn>=0) lines_m.append(QLineF(median, ymi-p.widthF()/2.0, median, yma+p.widthF()/2.0));
-
- if (meanColumn>=0 && JKQTPIsOKFloat(meanv)) {
- plotStyledSymbol(parent, painter, mean, y);
- }
-
- //first=true;
- painter.setPen(p);
- if (lines_p.size()>0) painter.drawLines(lines_p);
- painter.setPen(pw);
- if (lines_pw.size()>0) painter.drawLines(lines_pw);
- painter.setPen(pm);
- if (lines_m.size()>0) painter.drawLines(lines_m);
+ plotHorizontalBoxplot(parent, painter, y, ymi, yma, min, p25, median, p75, max, mean, medianu, mediano);
// add hit-test graph points
@@ -1108,15 +731,17 @@ void JKQTPBoxplotHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
JKQTPBoxplotVerticalElement::JKQTPBoxplotVerticalElement(JKQTBasePlotter* parent):
JKQTPPlotObject(parent)
{
- pos=0;
- median=0;
- mean=0;
- min=-1;
- max=1;
- drawMean=true;
- drawMinMax=true;
- percentile25=-0.75;
- percentile75=0.75;
+ pos=JKQTP_NAN;
+ median=JKQTP_NAN;
+ mean=JKQTP_NAN;
+ min=JKQTP_NAN;
+ max=JKQTP_NAN;
+ drawMean=false;
+ drawMinMax=false;
+ percentile25=JKQTP_NAN;
+ percentile75=JKQTP_NAN;
+ medianConfidenceIntervalWidth=JKQTP_NAN;
+ drawNotch=false;
initBoxplotStyle(parent, parentPlotStyle);
@@ -1137,20 +762,13 @@ void JKQTPBoxplotVerticalElement::draw(JKQTPEnhancedPainter& painter) {
{
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- QPen p=getLinePenForRects(painter, parent);
- QPen pw=getWhiskerPen(painter, parent);
- QPen pm=getMedianPen(painter, parent);
- QPen np(Qt::NoPen);
- QBrush b=getFillBrush(painter, parent);
-
-
-
const double xv=pos;
const double p25v=percentile25;
const double p75v=percentile75;
const double minv=min;
const double maxv=max;
const double medianv=median;
+ const double medConf=medianConfidenceIntervalWidth;
const double meanv=mean;
//std::cout<<"(xv, yv) = ( "<pt2px(painter, getBoxWidth());
+ double w=parent->pt2px(painter,getBoxWidthAbsolute());
double xma=x+w/2.0;
double xmi=x-w/2.0;
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- painter.setPen(p);
+ plotVerticalBoxplot(parent, painter, x, xmi, xma, (drawMinMax)?min:JKQTP_NAN, p25, (drawMedian)?median:JKQTP_NAN, p75, (drawMinMax)?max:JKQTP_NAN, (drawMean)?mean:JKQTP_NAN, (drawMedian&&drawNotch)?medianu:JKQTP_NAN, (drawMedian&&drawNotch)?mediano:JKQTP_NAN);
+
if (JKQTPIsOKFloat(p25v) && JKQTPIsOKFloat(p75v)) {
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- painter.setBrush(b);
- painter.drawRect(QRectF(xmi, p75, fabs(xma-xmi), fabs(p75-p25)));
if (JKQTPIsOKFloat(p25v)) {
QStringList sl=labelValues, sll=labelNames;
sl[labQ25]="\\ul{"+sl[labQ25]+"}";
@@ -1201,8 +825,6 @@ void JKQTPBoxplotVerticalElement::draw(JKQTPEnhancedPainter& painter) {
}
if (drawMedian && JKQTPIsOKFloat(medianv)) {
- painter.setPen(pm);
- painter.drawLine(QLineF(xmi, median, xma, median));
if (JKQTPIsOKFloat(medianv)) {
QStringList sl=labelValues, sll=labelNames;
sl[labMedian]="\\ul{"+sl[labMedian]+"}";
@@ -1211,11 +833,6 @@ void JKQTPBoxplotVerticalElement::draw(JKQTPEnhancedPainter& painter) {
}
}
if (drawMinMax) {
- painter.setPen(pw);
- if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(x-w/4.0, max, x+w/4.0, max));
- if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(x-w/4.0, min, x+w/4.0, min));
- if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(x, max, x, p75));
- if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(x, min, x, p25));
if (JKQTPIsOKFloat(minv)) {
QStringList sl=labelValues, sll=labelNames;
sl[labMin]="\\ul{"+sl[labMin]+"}";
@@ -1232,8 +849,6 @@ void JKQTPBoxplotVerticalElement::draw(JKQTPEnhancedPainter& painter) {
if (drawMean && JKQTPIsOKFloat(meanv)) {
- double mean=transformY(meanv);
- plotStyledSymbol(parent, painter, x, mean);
if (JKQTPIsOKFloat(meanv)) {
QStringList sl=labelValues, sll=labelNames;
sl[labMean]="\\ul{"+sl[labMean]+"}";
@@ -1327,6 +942,19 @@ double JKQTPBoxplotVerticalElement::getMedian() const
return this->median;
}
+void JKQTPBoxplotVerticalElement::setMedianConfidenceIntervalWidth(double __value)
+{
+ if (this->medianConfidenceIntervalWidth != __value) {
+ this->medianConfidenceIntervalWidth = __value;
+ drawNotch=true;
+ }
+}
+
+double JKQTPBoxplotVerticalElement::getMedianConfidenceIntervalWidth() const
+{
+ return this->medianConfidenceIntervalWidth;
+}
+
void JKQTPBoxplotVerticalElement::setMean(double __value)
{
if (this->mean != __value) {
@@ -1416,44 +1044,19 @@ bool JKQTPBoxplotVerticalElement::getDrawMinMax() const
return this->drawMinMax;
}
+void JKQTPBoxplotVerticalElement::setDrawNotch(bool __value)
+{
+ drawNotch=__value;
+}
+
+bool JKQTPBoxplotVerticalElement::getDrawNotch() const
+{
+ return drawNotch;
+}
+
void JKQTPBoxplotVerticalElement::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) {
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- QPen p=getLinePenForRects(painter, parent);
- QPen pw=getWhiskerPen(painter, parent);
- QPen pm=getMedianPen(painter, parent);
- QPen np(Qt::NoPen);
- QBrush b=getFillBrush(painter, parent);
- p.setWidthF(qMin(1.0, p.widthF()));
- pw.setWidthF(qMin(1.0, pw.widthF()));
- pm.setWidthF(qMin(1.0, pm.widthF()));
-
-
- double x=rect.left()+rect.width()/2.0;
- double xma=x+rect.width()/2.5;
- double xmi=x-rect.width()/2.5;
- double min=rect.bottom();
- double max=rect.top();
- double median=max+rect.height()/2.0;
- double w=rect.width()/1.8;
- double p25=max+0.75*rect.height();
- double p75=max+0.25*rect.height();
-
- painter.setPen(p);
- {
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- painter.setBrush(b);
- painter.drawRect(QRectF(xmi, p75, fabs(xma-xmi), fabs(p75-p25)));
- }
-
- painter.setPen(pm);
- painter.drawLine(QLineF(xmi, median, xma, median));
- painter.setPen(pw);
- painter.drawLine(QLineF(x-w/4.0, max, x+w/4.0, max));
- painter.drawLine(QLineF(x-w/4.0, min, x+w/4.0, min));
- painter.drawLine(QLineF(x, max, x, p75));
- painter.drawLine(QLineF(x, min, x, p25));
-
+ plotVerticalKeyMarker(parent, painter, rect);
}
QColor JKQTPBoxplotVerticalElement::getKeyLabelColor() const {
@@ -1464,41 +1067,7 @@ QColor JKQTPBoxplotVerticalElement::getKeyLabelColor() const {
void JKQTPBoxplotHorizontalElement::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) {
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- QPen p=getLinePenForRects(painter, parent);
- QPen pw=getWhiskerPen(painter, parent);
- QPen pm=getMedianPen(painter, parent);
- QPen np(Qt::NoPen);
- QBrush b=getFillBrush(painter, parent);
- p.setWidthF(qMin(1.0, p.widthF()));
- pw.setWidthF(qMin(1.0, pw.widthF()));
- pm.setWidthF(qMin(1.0, pm.widthF()));
-
- double y=rect.top()+rect.height()/2.0;
- double yma=y+rect.height()/2.5;
- double ymi=y-rect.height()/2.5;
- double min=rect.left();
- double max=rect.right();
- double median=max-rect.width()/2.0;
- double w=rect.height()/1.8;
- double p25=min+0.75*rect.width();
- double p75=min+0.25*rect.width();
-
- painter.setPen(p);
- {
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- painter.setBrush(b);
- painter.drawRect(QRectF(p75, ymi, fabs(p75-p25), fabs(yma-ymi)));
- }
-
- painter.setPen(pm);
- painter.drawLine(QLineF(median, ymi, median, yma));
- painter.setPen(pw);
- painter.drawLine(QLineF(max, y-w/4.0, max, y+w/4.0));
- painter.drawLine(QLineF(min, y-w/4.0, min, y+w/4.0));
- painter.drawLine(QLineF(max, y, p75, y));
- painter.drawLine(QLineF(min, y, p25, y));
-
+ plotHorizontalKeyMarker(parent, painter, rect);
}
bool JKQTPBoxplotHorizontalElement::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) {
@@ -1576,17 +1145,13 @@ void JKQTPBoxplotHorizontalElement::draw(JKQTPEnhancedPainter& painter) {
{
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- QPen p=getLinePenForRects(painter, parent);
- QPen pw=getWhiskerPen(painter, parent);
- QPen pm=getMedianPen(painter, parent);
- QPen np(Qt::NoPen);
- QBrush b=getFillBrush(painter, parent);
const double yv=pos;
const double p25v=percentile25;
const double p75v=percentile75;
const double minv=min;
const double maxv=max;
const double medianv=median;
+ const double medConf=medianConfidenceIntervalWidth;
const double meanv=mean;
//std::cout<<"(xv, yv) = ( "<pt2px(painter, getBoxWidth());
+ double w=parent->pt2px(painter,getBoxWidthAbsolute());
double yma=y+w/2.0;
double ymi=y-w/2.0;
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- painter.setPen(p);
+ plotHorizontalBoxplot(parent, painter, y, ymi, yma, (drawMinMax)?min:JKQTP_NAN, p25, (drawMedian)?median:JKQTP_NAN, p75, (drawMinMax)?max:JKQTP_NAN, (drawMean)?mean:JKQTP_NAN, (drawMedian&&drawNotch)?medianu:JKQTP_NAN, (drawMedian&&drawNotch)?mediano:JKQTP_NAN);
+
if (JKQTPIsOKFloat(p25v) && JKQTPIsOKFloat(p75v)) {
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- painter.setBrush(b);
- painter.drawRect(QRectF(p25, ymi, fabs(p75-p25), fabs(yma-ymi)));
if (JKQTPIsOKFloat(p25v)) {
QStringList sl=labelValues, sll=labelNames;
sl[labQ25]="\\ul{"+sl[labQ25]+"}";
@@ -1637,20 +1208,13 @@ void JKQTPBoxplotHorizontalElement::draw(JKQTPEnhancedPainter& painter) {
}
if (drawMedian && JKQTPIsOKFloat(medianv)) {
- painter.setPen(pm);
- painter.drawLine(QLineF(median, ymi, median, yma));
- if (JKQTPIsOKFloat(medianv)) {
+ if (JKQTPIsOKFloat(medianv)) {
QStringList sl=labelValues, sll=labelNames;
sl[labMedian]="\\ul{"+sl[labMedian]+"}";
sll[labMedian]="\\ul{"+sll[labMedian]+"}";
addHitTestData(medianv, yv, "\\ensuremath{\\begin{bmatrix}"+sll.join("\\\\")+"\\end{bmatrix}\\;=\\;\\begin{bmatrix}"+sl.join("\\\\")+"\\end{bmatrix}}");
} }
if (drawMinMax) {
- painter.setPen(pw);
- if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(max, y-w/4.0, max, y+w/4.0));
- if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(min, y-w/4.0, min, y+w/4.0));
- if (JKQTPIsOKFloat(maxv)) painter.drawLine(QLineF(max, y, p75, y));
- if (JKQTPIsOKFloat(minv)) painter.drawLine(QLineF(min, y, p25, y));
if (JKQTPIsOKFloat(minv)) {
QStringList sl=labelValues, sll=labelNames;
sl[labMin]="\\ul{"+sl[labMin]+"}";
@@ -1667,8 +1231,6 @@ void JKQTPBoxplotHorizontalElement::draw(JKQTPEnhancedPainter& painter) {
if (drawMean && JKQTPIsOKFloat(meanv)) {
- double mean=transformY(meanv);
- plotStyledSymbol(parent, painter, mean, y);
if (JKQTPIsOKFloat(meanv)) {
QStringList sl=labelValues, sll=labelNames;
sl[labMean]="\\ul{"+sl[labMean]+"}";
@@ -1697,7 +1259,7 @@ void JKQTPBoxplotVerticalGraph::intSortData()
JKQTPDatastore* datastore=parent->getDatastore();
int imin=0;
- int imax=datastore->getColumn(posColumn).getRows();
+ int imax=static_cast(datastore->getColumn(static_cast(posColumn)).getRows());
if (imaxget(posColumn,i);
+ double xv=datastore->get(posColumn,static_cast(i));
sortedIndices< &pattern);
- /** \brief gets the dash pattern for a custom dash style of whisker lines
- * \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
- */
- QVector getWhiskerLineDashPattern() const;
- /** \brief sets the join style of whisker lines
- * \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
- */
- void setWhiskerLineJoinStyle(Qt::PenJoinStyle style);
- /** \brief returns the join style of whisker lines
- * \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
- */
- Qt::PenJoinStyle getWhiskerLineJoinStyle() const;
- /** \brief sets the cap style of whisker lines
- * \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
- */
- void setWhiskerLineCapStyle(Qt::PenCapStyle style);
- /** \brief gets the cap style of whisker lines
- * \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
- */
- Qt::PenCapStyle getWhiskerLineCapStyle() const;
- /** \brief sets the brush used to fill the line area of whisker lines
- * \see https://doc.qt.io/qt-5/qpen.html#setBrush
- */
- void setWhiskerLineBrush(const QBrush& style);
- /** \brief gets the brush used to fill the line area of whisker lines
- * \see https://doc.qt.io/qt-5/qpen.html#setBrush
- */
- QBrush getWhiskerLineBrush() const;
-
- /** \brief build a pen to be used for drawing whiskers */
- QPen getWhiskerPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const;
-
-
-
-
-
-
-
- /*! \brief set the line style of median lines */
- void setMedianLineStyle(Qt::PenStyle __value);
- /*! \brief get the line style of median lines */
- Qt::PenStyle getMedianLineStyle() const;
-
- /*! \brief set the width [pt] of median lines */
- void setMedianLineWidth(double __value);
- /*! \brief get the width [pt] of median lines */
- double getMedianLineWidth() const;
-
- /*! \brief set the color of median lines */
- void setMedianLineColor(QColor __value);
- /*! \brief get the color of median lines */
- QColor getMedianLineColor() const;
-
-
- /** \brief sets the dash offset for a custom dash style of median lines
- * \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
- */
- void setMedianLineDashOffset(qreal offset);
- /** \brief returns the dash offset for a custom dash style of median lines
- * \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
- */
- qreal getMedianLineDashOffset() const;
- /** \brief sets the dash pattern for a custom dash style of median lines
- * \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
- */
- void setMedianLineDashPattern(const QVector &pattern);
- /** \brief gets the dash pattern for a custom dash style of median lines
- * \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
- */
- QVector getMedianLineDashPattern() const;
- /** \brief sets the join style of median lines
- * \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
- */
- void setMedianLineJoinStyle(Qt::PenJoinStyle style);
- /** \brief returns the join style of median lines
- * \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
- */
- Qt::PenJoinStyle getMedianLineJoinStyle() const;
- /** \brief sets the cap style of median lines
- * \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
- */
- void setMedianLineCapStyle(Qt::PenCapStyle style);
- /** \brief gets the cap style of median lines
- * \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
- */
- Qt::PenCapStyle getMedianLineCapStyle() const;
- /** \brief sets the brush used to fill the line area of median lines
- * \see https://doc.qt.io/qt-5/qpen.html#setBrush
- */
- void setMedianLineBrush(const QBrush& style);
- /** \brief gets the brush used to fill the line area of median lines
- * \see https://doc.qt.io/qt-5/qpen.html#setBrush
- */
- QBrush getMedianLineBrush() const;
-
- /** \brief build a pen to be used for drawing medians */
- QPen getMedianPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const;
-
- protected:
- /*! \brief set the color of the graph (colors all elements, based on the given color \a c )*/
- void setBoxplotColor(QColor c, JKQTBasePlotter *parent);
- private:
- /** \brief line style of the whisker lines */
- QPen m_whiskerLinePen;
- /** \brief line width (in pt) of the whisker lines */
- double whiskerLineWidth;
- /** \brief line style of the median lines */
- QPen m_medianLinePen;
- /** \brief line width (in pt) of the median lines */
- double medianLineWidth;
- /** \brief width of box in percent of distance between the current two posColumn values
- * if we only plot one box&whiskers then this is the width in pt */
- double boxWidth;
-
-};
-
-
-
-
-
-
-/*! \brief This implements vertical boxplots
+/*! \brief This implements vertical boxplots, optionally also a notched boxplot
\ingroup jkqtplotter_statgraphs
The x position is given in posColumn. All other data are given in the medianColumn, minColumn, maxColumn,
@@ -213,9 +43,15 @@ class JKQTP_LIB_EXPORT JKQTPGraphBoxplotStyleMixin: public JKQTPGraphLineStyleMi
\image html plot_boxplotvertical.png
+
The different features of a boxplot are:
- \image html boxplots.png
+ \image html plot_boxplotverticalelement.png
+
+
+ The example \ref JKQTPlotterBoxplotStyling discusses different options to style boxplots:
+
+ \image html test_styledboxplot.png
This class also implements hitTest() in a way that displays all data of the boxplot in the tooltips:
@@ -381,14 +217,43 @@ class JKQTP_LIB_EXPORT JKQTPBoxplotVerticalGraph: public JKQTPGraph, public JKQT
\details Description of the parameter percentile75Column is: \copydoc percentile75Column
\see percentile75Column for more information */
void setPercentile75Column (size_t __value);
+ /*! \copydoc medianConfidenceColumn
+ \see see medianConfidenceColumn for details */
+ int getMedianConfidenceColumn() const;
+ /*! \brief sets the property medianConfidenceColumn ( \copybrief medianConfidenceColumn ) to the specified \a __value, where __value is static_cast'ed from size_t to int.
+ \details Description of the parameter medianConfidenceColumn is: \copydoc medianConfidenceColumn
+ \see medianConfidenceColumn for more information */
+ void setMedianConfidenceColumn (size_t __value);
+ /*! \copydoc boxWidthRelative
+ \see see boxWidthRelative for details */
+ void setBoxWidthRelative(double __value);
+ /*! \copydoc boxWidthRelative
+ \see see boxWidthRelative for details */
+ double getBoxWidthRelative() const;
+
+
+ /*! \copydoc useRelativeBoxWidth
+ \see see useRelativeBoxWidth for details */
+ void setUseRelativeBoxWidth(bool __value);
+ /*! \copydoc useRelativeBoxWidth
+ \see see useRelativeBoxWidth for details */
+ bool getUseRelativeBoxWidth() const;
protected:
+ /** \brief width of box in percent of distance between the current two posColumn values
+ * if we only plot one box&whiskers then JKQTPGraphBoxplotStyleMixin::boxWidthAbsolute in pt is used */
+ double boxWidthRelative;
+ /** \brief if set \c true, boxplot widths are calculated automatically, based on boxWidthRelative,
+ * otherwise JKQTPGraphBoxplotStyleMixin::boxWidthAbsolute is used. */
+ bool useRelativeBoxWidth;
/** \brief the column that contains the x-component of the datapoints */
int posColumn;
/** \brief the column that contains the median-component of the datapoints */
int medianColumn;
+ /** \brief the column that contains the confidence interval width of the median (e.g. 1.57*IQR/sqrt(n) ). This is used to draw a notch in the plot (if set) */
+ int medianConfidenceColumn;
/** \brief the column that contains the median-component of the datapoints. \note This column is strictly optional. */
int meanColumn;
/** \brief the column that contains the minimum-component of the datapoints */
@@ -414,7 +279,7 @@ class JKQTP_LIB_EXPORT JKQTPBoxplotVerticalGraph: public JKQTPGraph, public JKQT
};
-/*! \brief This implements horizontal boxplots
+/*! \brief This implements horizontal boxplots, optionally also a notched boxplot
\ingroup jkqtplotter_statgraphs
the x position is given in posColumn. All other data are given in the medianColumn, minColumn, maxColumn,
@@ -459,20 +324,25 @@ class JKQTP_LIB_EXPORT JKQTPBoxplotHorizontalGraph: public JKQTPBoxplotVerticalG
-/*! \brief This implements a single vertical boxplot as a "geometric element",
+/*! \brief This implements a single vertical (notched) boxplot as a "geometric element",
where the data is directly given to the object and not stored in a column, as in JKQTPBoxplotVerticalGraph
\ingroup jkqtplotter_statgraphs
\ingroup jkqtplotter_geoplots
- \image html plot_boxplotverticalelement.png
the x position is given in posColumn. All other data are given in the median, min, max,
percentile25 and percentile75.
The different features of a boxplot are:
- \image html boxplots.png
+ \image html plot_boxplotverticalelement.png
+
+
+ The example \ref JKQTPlotterBoxplotStyling discusses different options to style boxplots:
+
+ \image html test_styledboxplot.png
+
*/
class JKQTP_LIB_EXPORT JKQTPBoxplotVerticalElement: public JKQTPPlotObject, public JKQTPGraphBoxplotStyleMixin {
Q_OBJECT
@@ -563,14 +433,30 @@ class JKQTP_LIB_EXPORT JKQTPBoxplotVerticalElement: public JKQTPPlotObject, publ
/*! \copydoc drawMinMax
\see see drawMinMax for details */
bool getDrawMinMax() const;
+ /*! \copydoc drawNotch
+ \see see drawNotch for details */
+ void setDrawNotch(bool __value);
+ /*! \copydoc drawNotch
+ \see see drawNotch for details */
+ bool getDrawNotch() const;
+ /*! \copydoc medianConfidenceIntervalWidth
+ \see see medianConfidenceIntervalWidth for details */
+ double getMedianConfidenceIntervalWidth() const;
+ /*! \copydoc medianConfidenceIntervalWidth
+ \see see medianConfidenceIntervalWidth for details */
+ void setMedianConfidenceIntervalWidth(double __value);
protected:
- /** \brief the column that contains the x-component of the datapoints */
+ /** \brief the position of the boxplot on the "other" axis */
double pos;
- /** \brief the column that contains the median-component of the datapoints */
+ /** \brief the median value to be used for the boxplot */
double median;
- /** \brief the column that contains the median-component of the datapoints. \note This column is strictly optional. */
+ /** \brief the width of the confidence interval around the median */
+ double medianConfidenceIntervalWidth;
+ /** \brief indicates whether to draw a notch with width medianConfidenceIntervalWidth */
+ bool drawNotch;
+ /** \brief the mean value to be used for the boxplot */
double mean;
/** \brief indicates whether to draw the mean */
bool drawMean;
@@ -578,18 +464,18 @@ class JKQTP_LIB_EXPORT JKQTPBoxplotVerticalElement: public JKQTPPlotObject, publ
bool drawMedian;
/** \brief indicates whether to draw the percentiles */
bool drawMinMax;
- /** \brief the column that contains the minimum-component of the datapoints */
+ /** \brief the minimum value to be used for the boxplot */
double min;
- /** \brief the column that contains the maximum-component of the datapoints */
+ /** \brief the maximum value to be used for the boxplot */
double max;
- /** \brief the column that contains the 25% percentile-component of the datapoints */
+ /** \brief the 25% percentile value to be used for the boxplot */
double percentile25;
- /** \brief the column that contains the 75% percentile-component of the datapoints */
+ /** \brief the 75% percentile value to be used for the boxplot */
double percentile75;
};
-/*! \brief This implements a horizontal boxplot where the data is directly given to the
+/*! \brief This implements a horizontal (notched) boxplot where the data is directly given to the
object and not stored in a column, as in JKQTPBoxplotVerticalGraph
\ingroup jkqtplotter_statgraphs
\ingroup jkqtplotter_geoplots
diff --git a/lib/jkqtplotter/jkqtpgraphsboxplotstylingmixins.cpp b/lib/jkqtplotter/jkqtpgraphsboxplotstylingmixins.cpp
new file mode 100644
index 0000000000..95a973af5c
--- /dev/null
+++ b/lib/jkqtplotter/jkqtpgraphsboxplotstylingmixins.cpp
@@ -0,0 +1,785 @@
+/*
+ Copyright (c) 2008-2019 Jan W. Krieger ()
+
+
+
+ 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
+ the Free Software Foundation, either version 2.1 of the License, or
+ (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 .
+*/
+
+
+
+#include "jkqtplotter/jkqtpgraphsboxplotstylingmixins.h"
+#include "jkqtplotter/jkqtpbaseplotter.h"
+#include
+#include
+#include
+#include "jkqtplottertools/jkqtptools.h"
+#include "jkqtplotter/jkqtpgraphsimage.h"
+#include "jkqtplotter/jkqtpbaseelements.h"
+#include "jkqtplotter/jkqtplotter.h"
+
+
+
+JKQTPGraphBoxplotStyleMixin::JKQTPGraphBoxplotStyleMixin()
+{
+
+ m_whiskerLinePen=QPen(getLineColor(), getLineWidth());
+ whiskerLineWidth=getLineWidth();
+ m_whiskerCapLinePen=QPen(getLineColor(), getLineWidth());
+ whiskerCapLineWidth=getLineWidth();
+ m_medianLinePen=QPen(getLineColor(), getLineWidth());
+ medianLineWidth=getLineWidth();
+
+ m_meanSymbolLinePen=QPen(getLineColor(), getLineWidth());
+ m_meanSymbolLineWidth=1;
+ meanMode=MeanAsSymbol;
+ m_meanSymbolType=JKQTPGraphSymbols::JKQTPDefaultSymbol;
+ m_meanSymbolSize=12;
+ m_meanSymbolFillColor=m_meanSymbolLinePen.color().lighter();
+
+
+ boxWidthAbsolute=m_meanSymbolSize*3.0;
+ relativeWhiskerWidth=0.5;
+ relativeNotchIndent=0.25;
+ drawBox=true;
+
+}
+
+
+void JKQTPGraphBoxplotStyleMixin::initBoxplotStyle(JKQTBasePlotter *parent, int &parentPlotStyle)
+{
+ setFillStyle(Qt::SolidPattern);
+ setFillColor(parent->getCurrentPlotterStyle().plotBackgroundBrush.color());
+ initLineStyle(parent, parentPlotStyle);
+ if (parent) { // get style settings from parent object
+ if (parentPlotStyle<0) parentPlotStyle=parent->getNextStyle();
+ m_whiskerLinePen.setColor(parent->getPlotStyle(parentPlotStyle).color());
+ m_whiskerLinePen.setStyle(parent->getPlotStyle(parentPlotStyle).style());
+ whiskerLineWidth=parent->getPlotStyle(parentPlotStyle).widthF();
+ m_whiskerCapLinePen.setColor(parent->getPlotStyle(parentPlotStyle).color());
+ m_whiskerCapLinePen.setStyle(parent->getPlotStyle(parentPlotStyle).style());
+ whiskerCapLineWidth=parent->getPlotStyle(parentPlotStyle).widthF();
+ m_medianLinePen.setColor(parent->getPlotStyle(parentPlotStyle).color());
+ m_medianLinePen.setStyle(parent->getPlotStyle(parentPlotStyle).style());
+ medianLineWidth=parent->getPlotStyle(parentPlotStyle).widthF();
+ m_meanSymbolLinePen=QPen(parent->getPlotStyle(parentPlotStyle).color(), parent->getPlotStyle(parentPlotStyle).style());
+ m_meanSymbolSize=parent->getPlotStyle(parentPlotStyle).symbolSize();
+ m_meanSymbolLineWidth=parent->getPlotStyle(parentPlotStyle).symbolLineWidthF();
+ m_meanSymbolType=parent->getPlotStyle(parentPlotStyle).symbol();
+ m_meanSymbolFillColor=parent->getPlotStyle(parentPlotStyle).symbolFillColor();
+ }
+
+ setWhiskerLineColor(getLineColor());
+ setWhiskerCapLineColor(getLineColor());
+ setMedianLineColor(getLineColor());
+
+ if (m_meanSymbolSize>0) {
+ boxWidthAbsolute=m_meanSymbolSize*3.0;
+ }
+}
+
+void JKQTPGraphBoxplotStyleMixin::setBoxWidthAbsolute(double __value)
+{
+ boxWidthAbsolute=__value;
+}
+
+double JKQTPGraphBoxplotStyleMixin::getBoxWidthAbsolute() const
+{
+ return boxWidthAbsolute;
+}
+
+void JKQTPGraphBoxplotStyleMixin::setBoxplotColor(QColor c, JKQTBasePlotter *parent)
+{
+ setLineColor(c);
+ setFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphFillColorDerivationMode, c));
+ setMeanColor(c);
+ setMeanFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphFillColorDerivationMode, c));
+ setWhiskerLineColor(getLineColor());
+ setWhiskerCapLineColor(getLineColor());
+ setMedianLineColor(getLineColor());
+ c.setAlphaF(0.5);
+ setHighlightingLineColor(c);
+}
+
+void JKQTPGraphBoxplotStyleMixin::setBoxplotColor(QColor c, QColor bc, JKQTBasePlotter *parent)
+{
+ setBoxplotColor(c, parent);
+ setFillColor(bc);
+ setMeanFillColor(bc);
+}
+
+void JKQTPGraphBoxplotStyleMixin::setDrawBox(bool __value)
+{
+ drawBox=__value;
+}
+
+bool JKQTPGraphBoxplotStyleMixin::getDrawBox() const
+{
+ return drawBox;
+}
+
+void JKQTPGraphBoxplotStyleMixin::setRelativeWhiskerWidth(double __value)
+{
+ relativeWhiskerWidth=__value;
+}
+
+double JKQTPGraphBoxplotStyleMixin::getRelativeWhiskerWidth() const
+{
+ return relativeWhiskerWidth;
+}
+
+void JKQTPGraphBoxplotStyleMixin::setRelativeNotchIndent(double __value)
+{
+ relativeNotchIndent=__value;
+}
+
+double JKQTPGraphBoxplotStyleMixin::getRelativeNotchIndent() const
+{
+ return relativeNotchIndent;
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMeanMode(JKQTPGraphBoxplotStyleMixin::MeanMode __value)
+{
+ meanMode=__value;
+}
+
+JKQTPGraphBoxplotStyleMixin::MeanMode JKQTPGraphBoxplotStyleMixin::getMeanMode() const
+{
+ return meanMode;
+}
+
+
+
+
+
+
+
+void JKQTPGraphBoxplotStyleMixin::setMeanSymbolType(JKQTPGraphSymbols __value)
+{
+ m_meanSymbolType=__value;
+}
+
+JKQTPGraphSymbols JKQTPGraphBoxplotStyleMixin::getMeanSymbolType() const
+{
+ return m_meanSymbolType;
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMeanSize(double __value)
+{
+ m_meanSymbolSize=__value;
+}
+
+double JKQTPGraphBoxplotStyleMixin::getMeanSize() const
+{
+ return m_meanSymbolSize;
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMeanColor(const QColor &__value)
+{
+ m_meanSymbolLinePen.setColor(__value);
+}
+
+QColor JKQTPGraphBoxplotStyleMixin::getMeanColor() const
+{
+ return m_meanSymbolLinePen.color();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMeanFillColor(const QColor &__value)
+{
+ m_meanSymbolFillColor=__value;
+}
+
+QColor JKQTPGraphBoxplotStyleMixin::getMeanFillColor() const
+{
+ return m_meanSymbolFillColor;
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMeanLineWidth(double __value)
+{
+ m_meanSymbolLineWidth=__value;
+}
+
+double JKQTPGraphBoxplotStyleMixin::getMeanLineWidth() const
+{
+ return m_meanSymbolLineWidth;
+}
+
+
+void JKQTPGraphBoxplotStyleMixin::setMeanLineStyle(Qt::PenStyle __value)
+{
+ this->m_meanSymbolLinePen.setStyle(__value);
+}
+
+Qt::PenStyle JKQTPGraphBoxplotStyleMixin::getMeanLineStyle() const
+{
+ return this->m_meanSymbolLinePen.style();
+}
+
+
+void JKQTPGraphBoxplotStyleMixin::setMeanLineDashOffset(qreal offset)
+{
+ m_meanSymbolLinePen.setDashOffset(offset);
+}
+
+qreal JKQTPGraphBoxplotStyleMixin::getMeanLineDashOffset() const
+{
+ return m_meanSymbolLinePen.dashOffset();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMeanLineDashPattern(const QVector &pattern)
+{
+ m_meanSymbolLinePen.setDashPattern(pattern);
+ m_meanSymbolLinePen.setStyle(Qt::CustomDashLine);
+}
+
+QVector JKQTPGraphBoxplotStyleMixin::getMeanLineDashPattern() const
+{
+ return m_meanSymbolLinePen.dashPattern();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMedianLineWidth(double __value)
+{
+ medianLineWidth=__value;
+}
+
+double JKQTPGraphBoxplotStyleMixin::getMedianLineWidth() const
+{
+ return medianLineWidth;
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMedianLineColor(QColor __value)
+{
+ m_medianLinePen.setColor(__value);
+}
+
+QColor JKQTPGraphBoxplotStyleMixin::getMedianLineColor() const
+{
+ return m_medianLinePen.color();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMedianLineStyle(Qt::PenStyle __value)
+{
+ this->m_medianLinePen.setStyle(__value);
+}
+
+Qt::PenStyle JKQTPGraphBoxplotStyleMixin::getMedianLineStyle() const
+{
+ return this->m_medianLinePen.style();
+}
+
+
+void JKQTPGraphBoxplotStyleMixin::setMedianLineDashOffset(qreal offset)
+{
+ m_medianLinePen.setDashOffset(offset);
+}
+
+qreal JKQTPGraphBoxplotStyleMixin::getMedianLineDashOffset() const
+{
+ return m_medianLinePen.dashOffset();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMedianLineDashPattern(const QVector &pattern)
+{
+ m_medianLinePen.setDashPattern(pattern);
+ m_medianLinePen.setStyle(Qt::CustomDashLine);
+}
+
+QVector JKQTPGraphBoxplotStyleMixin::getMedianLineDashPattern() const
+{
+ return m_medianLinePen.dashPattern();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMedianLineJoinStyle(Qt::PenJoinStyle style)
+{
+ m_medianLinePen.setJoinStyle(style);
+}
+
+Qt::PenJoinStyle JKQTPGraphBoxplotStyleMixin::getMedianLineJoinStyle() const
+{
+ return m_medianLinePen.joinStyle();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMedianLineCapStyle(Qt::PenCapStyle style)
+{
+ m_medianLinePen.setCapStyle(style);
+}
+
+Qt::PenCapStyle JKQTPGraphBoxplotStyleMixin::getMedianLineCapStyle() const
+{
+ return m_medianLinePen.capStyle();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setMedianLineBrush(const QBrush &style)
+{
+ m_medianLinePen.setBrush(style);
+}
+
+QBrush JKQTPGraphBoxplotStyleMixin::getMedianLineBrush() const
+{
+ return m_medianLinePen.brush();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerLineStyle(Qt::PenStyle __value)
+{
+ this->m_whiskerLinePen.setStyle(__value);
+}
+
+Qt::PenStyle JKQTPGraphBoxplotStyleMixin::getWhiskerLineStyle() const
+{
+ return this->m_whiskerLinePen.style();
+}
+
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerLineWidth(double __value)
+{
+ whiskerLineWidth=__value;
+}
+
+double JKQTPGraphBoxplotStyleMixin::getWhiskerLineWidth() const
+{
+ return whiskerLineWidth;
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerLineColor(QColor __value)
+{
+ m_whiskerLinePen.setColor(__value);
+}
+
+QColor JKQTPGraphBoxplotStyleMixin::getWhiskerLineColor() const
+{
+ return m_whiskerLinePen.color();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerLineDashOffset(qreal offset)
+{
+ m_whiskerLinePen.setDashOffset(offset);
+}
+
+qreal JKQTPGraphBoxplotStyleMixin::getWhiskerLineDashOffset() const
+{
+ return m_whiskerLinePen.dashOffset();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerLineDashPattern(const QVector &pattern)
+{
+ m_whiskerLinePen.setDashPattern(pattern);
+ m_whiskerLinePen.setStyle(Qt::CustomDashLine);
+}
+
+QVector JKQTPGraphBoxplotStyleMixin::getWhiskerLineDashPattern() const
+{
+ return m_whiskerLinePen.dashPattern();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerLineJoinStyle(Qt::PenJoinStyle style)
+{
+ m_whiskerLinePen.setJoinStyle(style);
+}
+
+Qt::PenJoinStyle JKQTPGraphBoxplotStyleMixin::getWhiskerLineJoinStyle() const
+{
+ return m_whiskerLinePen.joinStyle();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerLineCapStyle(Qt::PenCapStyle style)
+{
+ m_whiskerLinePen.setCapStyle(style);
+}
+
+Qt::PenCapStyle JKQTPGraphBoxplotStyleMixin::getWhiskerLineCapStyle() const
+{
+ return m_whiskerLinePen.capStyle();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerLineBrush(const QBrush &style)
+{
+ m_whiskerLinePen.setBrush(style);
+}
+
+QBrush JKQTPGraphBoxplotStyleMixin::getWhiskerLineBrush() const
+{
+ return m_whiskerLinePen.brush();
+}
+
+QPen JKQTPGraphBoxplotStyleMixin::getWhiskerPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const
+{
+ QPen pw=m_whiskerLinePen;
+ pw.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*whiskerLineWidth)));
+ pw.setJoinStyle(Qt::MiterJoin);
+ pw.setCapStyle(Qt::FlatCap);
+ return pw;
+}
+
+
+
+
+
+
+
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerCapLineStyle(Qt::PenStyle __value)
+{
+ this->m_whiskerCapLinePen.setStyle(__value);
+}
+
+Qt::PenStyle JKQTPGraphBoxplotStyleMixin::getWhiskerCapLineStyle() const
+{
+ return this->m_whiskerCapLinePen.style();
+}
+
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerCapLineWidth(double __value)
+{
+ whiskerCapLineWidth=__value;
+}
+
+double JKQTPGraphBoxplotStyleMixin::getWhiskerCapLineWidth() const
+{
+ return whiskerCapLineWidth;
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerCapLineColor(QColor __value)
+{
+ m_whiskerCapLinePen.setColor(__value);
+}
+
+QColor JKQTPGraphBoxplotStyleMixin::getWhiskerCapLineColor() const
+{
+ return m_whiskerCapLinePen.color();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerCapLineDashOffset(qreal offset)
+{
+ m_whiskerCapLinePen.setDashOffset(offset);
+}
+
+qreal JKQTPGraphBoxplotStyleMixin::getWhiskerCapLineDashOffset() const
+{
+ return m_whiskerCapLinePen.dashOffset();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerCapLineDashPattern(const QVector &pattern)
+{
+ m_whiskerCapLinePen.setDashPattern(pattern);
+ m_whiskerCapLinePen.setStyle(Qt::CustomDashLine);
+}
+
+QVector JKQTPGraphBoxplotStyleMixin::getWhiskerCapLineDashPattern() const
+{
+ return m_whiskerCapLinePen.dashPattern();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerCapLineJoinStyle(Qt::PenJoinStyle style)
+{
+ m_whiskerCapLinePen.setJoinStyle(style);
+}
+
+Qt::PenJoinStyle JKQTPGraphBoxplotStyleMixin::getWhiskerCapLineJoinStyle() const
+{
+ return m_whiskerCapLinePen.joinStyle();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerCapLineCapStyle(Qt::PenCapStyle style)
+{
+ m_whiskerCapLinePen.setCapStyle(style);
+}
+
+Qt::PenCapStyle JKQTPGraphBoxplotStyleMixin::getWhiskerCapLineCapStyle() const
+{
+ return m_whiskerCapLinePen.capStyle();
+}
+
+void JKQTPGraphBoxplotStyleMixin::setWhiskerCapLineBrush(const QBrush &style)
+{
+ m_whiskerCapLinePen.setBrush(style);
+}
+
+QBrush JKQTPGraphBoxplotStyleMixin::getWhiskerCapLineBrush() const
+{
+ return m_whiskerCapLinePen.brush();
+}
+
+QPen JKQTPGraphBoxplotStyleMixin::getWhiskerCapPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const
+{
+ QPen pw=m_whiskerCapLinePen;
+ pw.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*whiskerCapLineWidth)));
+ pw.setJoinStyle(Qt::MiterJoin);
+ return pw;
+}
+
+
+
+
+
+
+
+
+
+QPen JKQTPGraphBoxplotStyleMixin::getMedianPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const
+{
+ QPen pw=m_medianLinePen;
+ pw.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*medianLineWidth)));
+ pw.setJoinStyle(Qt::MiterJoin);
+ pw.setCapStyle(Qt::FlatCap);
+ return pw;
+}
+
+QPen JKQTPGraphBoxplotStyleMixin::getMeanSymbolPen(JKQTPEnhancedPainter& painter, JKQTBasePlotter* parent) const {
+ QPen p=m_meanSymbolLinePen;
+ p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_meanSymbolLineWidth)));
+ p.setStyle(Qt::SolidLine);
+ p.setJoinStyle(Qt::RoundJoin);
+ p.setCapStyle(Qt::RoundCap);
+ return p;
+}
+
+QPen JKQTPGraphBoxplotStyleMixin::getMeanLinePen(JKQTPEnhancedPainter& painter, JKQTBasePlotter* parent) const {
+ QPen p=m_meanSymbolLinePen;
+ p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH,parent->pt2px(painter, parent->getLineWidthMultiplier()*m_meanSymbolLineWidth)));
+ p.setJoinStyle(Qt::MiterJoin);
+ p.setCapStyle(Qt::FlatCap);
+ return p;
+}
+
+QBrush JKQTPGraphBoxplotStyleMixin::getMeanSymbolBrush(JKQTPEnhancedPainter& /*painter*/, JKQTBasePlotter* /*parent*/) const {
+ QBrush b;
+ b.setColor(m_meanSymbolFillColor);
+ return b;
+}
+
+void JKQTPGraphBoxplotStyleMixin::plotStyledMeanSymbol(JKQTBasePlotter *parent, JKQTPEnhancedPainter &painter, double x, double y) const
+{
+ JKQTPPlotSymbol(painter, x, y,m_meanSymbolType, parent->pt2px(painter, m_meanSymbolSize), parent->pt2px(painter, m_meanSymbolLineWidth*parent->getLineWidthMultiplier()), m_meanSymbolLinePen.color(), m_meanSymbolFillColor);
+}
+
+
+
+void JKQTPGraphBoxplotStyleMixin::plotVerticalBoxplot(JKQTBasePlotter *parent, JKQTPEnhancedPainter &painter, double xp, double xpleft, double xpright, double minp, double q25p, double medianp, double q75p, double maxp, double meanp, double notchLowerp, double notchUpperp) const
+{
+ if (JKQTPIsOKFloat(xp) ) {
+ painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
+ painter.setBrush(Qt::NoBrush);
+
+
+ double minstop=q25p;
+ double maxstop=q75p;
+ if (!JKQTPIsOKFloat(minstop) && JKQTPIsOKFloat(medianp)) minstop=medianp;
+ else if (!JKQTPIsOKFloat(minstop) && JKQTPIsOKFloat(meanp)) minstop=meanp;
+ else if (!JKQTPIsOKFloat(minstop) && JKQTPIsOKFloat(maxp)) minstop=maxp;
+ if (!JKQTPIsOKFloat(maxstop) && JKQTPIsOKFloat(medianp)) maxstop=medianp;
+ else if (!JKQTPIsOKFloat(maxstop) && JKQTPIsOKFloat(meanp)) maxstop=meanp;
+ else if (!JKQTPIsOKFloat(maxstop) && JKQTPIsOKFloat(minp)) maxstop=minp;
+ const double wl=fabs(xpright-xp);
+ const double wr=fabs(xpleft-xp);
+ const double xprightWhisker=xp+wr*getRelativeWhiskerWidth();
+ const double xpleftWhisker=xp-wl*getRelativeWhiskerWidth();
+
+ // whisker lines
+ painter.setPen(getWhiskerPen(painter, parent));
+ if (JKQTPIsOKFloat(minp) && JKQTPIsOKFloat(minstop)) {
+ painter.drawLine(QLineF(xp, minp, xp, minstop));
+ }
+ if (JKQTPIsOKFloat(maxp) && JKQTPIsOKFloat(maxstop)) {
+ painter.drawLine(QLineF(xp, maxp, xp, maxstop));
+ }
+
+ // whisker caps
+ if (JKQTPIsOKFloat(xpleftWhisker) && JKQTPIsOKFloat(xprightWhisker)){
+ painter.setPen(getWhiskerCapPen(painter, parent));
+ if (JKQTPIsOKFloat(minp)) {
+ painter.drawLine(QLineF(xpleftWhisker, minp, xprightWhisker, minp));
+ }
+ if (JKQTPIsOKFloat(maxp)) {
+ painter.drawLine(QLineF(xpleftWhisker, maxp, xprightWhisker, maxp));
+ }
+ }
+
+ // draw main box
+ double medianMin=xpleft;
+ double medianMax=xpright;
+ if (JKQTPIsOKFloat(q25p) && JKQTPIsOKFloat(q75p) && getDrawBox()) {
+ painter.setPen(getLinePenForRects(painter, parent));
+ painter.setBrush(getFillBrush(painter, parent));
+ if (getDrawBox()) {
+ QPolygonF poly;
+ if (JKQTPIsOKFloat(notchLowerp) && JKQTPIsOKFloat(notchUpperp)) {
+ // notched boxplot
+ poly<)
+
+
+
+ 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
+ the Free Software Foundation, either version 2.1 of the License, or
+ (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 .
+*/
+
+
+#include
+#include
+#include "jkqtplottertools/jkqtptools.h"
+#include "jkqtplottertools/jkqtp_imexport.h"
+#include "jkqtplotter/jkqtpgraphsbase.h"
+#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
+
+#ifndef jkqtpgraphsboxplotstylingmixins_H
+#define jkqtpgraphsboxplotstylingmixins_H
+
+
+
+
+
+/*! \brief Styling Mix-In for Boxplots
+ \ingroup jkqtplotter_basegraphs_stylemixins
+
+
+ \image html plot_boxplothorizontalelement.png
+
+ The example \ref JKQTPlotterBoxplotStyling discusses different options to style boxplots:
+
+ \image html test_styledboxplot.png
+ */
+class JKQTP_LIB_EXPORT JKQTPGraphBoxplotStyleMixin: public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
+ Q_GADGET
+ public:
+ /** \brief class constructor */
+ JKQTPGraphBoxplotStyleMixin();
+
+ void initBoxplotStyle(JKQTBasePlotter* parent, int &parentPlotStyle);
+ /*! \copydoc boxWidthAbsolute
+ \see see boxWidthAbsolute for details */
+ void setBoxWidthAbsolute(double __value);
+ /*! \copydoc boxWidthAbsolute
+ \see see boxWidthAbsolute for details */
+ double getBoxWidthAbsolute() const;
+
+ /*! \copydoc drawBox
+ \see see drawBox for details */
+ void setDrawBox(bool __value);
+ /*! \copydoc drawBox
+ \see see drawBox for details */
+ bool getDrawBox() const;
+
+ /*! \copydoc relativeWhiskerWidth
+ \see see relativeWhiskerWidth for details */
+ void setRelativeWhiskerWidth(double __value);
+ /*! \copydoc relativeWhiskerWidth
+ \see see relativeWhiskerWidth for details */
+ double getRelativeWhiskerWidth() const;
+
+ /*! \copydoc relativeNotchIndent
+ \see see relativeNotchIndent for details */
+ void setRelativeNotchIndent(double __value);
+ /*! \copydoc relativeNotchIndent
+ \see see relativeNotchIndent for details */
+ double getRelativeNotchIndent() const;
+
+
+ /*! \brief set the line style of whisker lines */
+ void setWhiskerLineStyle(Qt::PenStyle __value);
+ /*! \brief get the line style of whisker lines */
+ Qt::PenStyle getWhiskerLineStyle() const;
+
+ /*! \brief set the width [pt] of whisker lines */
+ void setWhiskerLineWidth(double __value);
+ /*! \brief get the width [pt] of whisker lines */
+ double getWhiskerLineWidth() const;
+
+ /*! \brief set the color of whisker lines */
+ void setWhiskerLineColor(QColor __value);
+ /*! \brief get the color of whisker lines */
+ QColor getWhiskerLineColor() const;
+
+
+ /** \brief sets the dash offset for a custom dash style of whisker lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
+ */
+ void setWhiskerLineDashOffset(qreal offset);
+ /** \brief returns the dash offset for a custom dash style of whisker lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
+ */
+ qreal getWhiskerLineDashOffset() const;
+ /** \brief sets the dash pattern for a custom dash style of whisker lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
+ */
+ void setWhiskerLineDashPattern(const QVector &pattern);
+ /** \brief gets the dash pattern for a custom dash style of whisker lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
+ */
+ QVector getWhiskerLineDashPattern() const;
+ /** \brief sets the join style of whisker lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
+ */
+ void setWhiskerLineJoinStyle(Qt::PenJoinStyle style);
+ /** \brief returns the join style of whisker lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
+ */
+ Qt::PenJoinStyle getWhiskerLineJoinStyle() const;
+ /** \brief sets the cap style of whisker lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
+ */
+ void setWhiskerLineCapStyle(Qt::PenCapStyle style);
+ /** \brief gets the cap style of whisker lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
+ */
+ Qt::PenCapStyle getWhiskerLineCapStyle() const;
+ /** \brief sets the brush used to fill the line area of whisker lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setBrush
+ */
+ void setWhiskerLineBrush(const QBrush& style);
+ /** \brief gets the brush used to fill the line area of whisker lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setBrush
+ */
+ QBrush getWhiskerLineBrush() const;
+
+ /** \brief build a pen to be used for drawing whiskers */
+ QPen getWhiskerPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const;
+
+
+
+ /*! \brief set the line style of whisker cap lines */
+ void setWhiskerCapLineStyle(Qt::PenStyle __value);
+ /*! \brief get the line style of whisker cap lines */
+ Qt::PenStyle getWhiskerCapLineStyle() const;
+
+ /*! \brief set the width [pt] of whisker cap lines */
+ void setWhiskerCapLineWidth(double __value);
+ /*! \brief get the width [pt] of whisker cap lines */
+ double getWhiskerCapLineWidth() const;
+
+ /*! \brief set the color of whisker cap lines */
+ void setWhiskerCapLineColor(QColor __value);
+ /*! \brief get the color of whisker cap lines */
+ QColor getWhiskerCapLineColor() const;
+
+
+ /** \brief sets the dash offset for a custom dash style of whisker cap lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
+ */
+ void setWhiskerCapLineDashOffset(qreal offset);
+ /** \brief returns the dash offset for a custom dash style of whisker cap lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
+ */
+ qreal getWhiskerCapLineDashOffset() const;
+ /** \brief sets the dash pattern for a custom dash style of whisker cap lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
+ */
+ void setWhiskerCapLineDashPattern(const QVector &pattern);
+ /** \brief gets the dash pattern for a custom dash style of whisker cap lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
+ */
+ QVector getWhiskerCapLineDashPattern() const;
+ /** \brief sets the join style of whisker cap lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
+ */
+ void setWhiskerCapLineJoinStyle(Qt::PenJoinStyle style);
+ /** \brief returns the join style of whisker cap lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
+ */
+ Qt::PenJoinStyle getWhiskerCapLineJoinStyle() const;
+ /** \brief sets the cap style of whisker cap lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
+ */
+ void setWhiskerCapLineCapStyle(Qt::PenCapStyle style);
+ /** \brief gets the cap style of whisker cap lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
+ */
+ Qt::PenCapStyle getWhiskerCapLineCapStyle() const;
+ /** \brief sets the brush used to fill the line area of whisker cap lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setBrush
+ */
+ void setWhiskerCapLineBrush(const QBrush& style);
+ /** \brief gets the brush used to fill the line area of whisker cap lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setBrush
+ */
+ QBrush getWhiskerCapLineBrush() const;
+
+ /** \brief build a pen to be used for drawing whisker caps */
+ QPen getWhiskerCapPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const;
+
+
+
+
+ /** \brief modes of how to draw the mean in a boxplot */
+ enum MeanMode {
+ MeanAsSymbol, /*!< \brief draw mean as a symbol (specified by the settings in JKQTPGraphSymbolStyleMixin) */
+ MeanAsLine /*!< \brief draw mean as a lie (specified by the pen settings in JKQTPGraphSymbolStyleMixin) */
+ };
+
+ /*! \copydoc meanMode
+ \see see meanMode for details */
+ void setMeanMode(MeanMode __value);
+ /*! \copydoc meanMode
+ \see see meanMode for details */
+ MeanMode getMeanMode() const;
+
+
+ /*! \brief set the line style of median lines */
+ void setMedianLineStyle(Qt::PenStyle __value);
+ /*! \brief get the line style of median lines */
+ Qt::PenStyle getMedianLineStyle() const;
+
+ /*! \brief set the width [pt] of median lines */
+ void setMedianLineWidth(double __value);
+ /*! \brief get the width [pt] of median lines */
+ double getMedianLineWidth() const;
+
+ /*! \brief set the color of median lines */
+ void setMedianLineColor(QColor __value);
+ /*! \brief get the color of median lines */
+ QColor getMedianLineColor() const;
+
+
+ /** \brief sets the dash offset for a custom dash style of median lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
+ */
+ void setMedianLineDashOffset(qreal offset);
+ /** \brief returns the dash offset for a custom dash style of median lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
+ */
+ qreal getMedianLineDashOffset() const;
+ /** \brief sets the dash pattern for a custom dash style of median lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
+ */
+ void setMedianLineDashPattern(const QVector &pattern);
+ /** \brief gets the dash pattern for a custom dash style of median lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
+ */
+ QVector getMedianLineDashPattern() const;
+ /** \brief sets the join style of median lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
+ */
+ void setMedianLineJoinStyle(Qt::PenJoinStyle style);
+ /** \brief returns the join style of median lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setJoinStyle
+ */
+ Qt::PenJoinStyle getMedianLineJoinStyle() const;
+ /** \brief sets the cap style of median lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
+ */
+ void setMedianLineCapStyle(Qt::PenCapStyle style);
+ /** \brief gets the cap style of median lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setCapStyle
+ */
+ Qt::PenCapStyle getMedianLineCapStyle() const;
+ /** \brief sets the brush used to fill the line area of median lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setBrush
+ */
+ void setMedianLineBrush(const QBrush& style);
+ /** \brief gets the brush used to fill the line area of median lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setBrush
+ */
+ QBrush getMedianLineBrush() const;
+
+ /** \brief build a pen to be used for drawing medians */
+ QPen getMedianPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter *parent) const;
+
+
+
+
+
+ /*! \brief set the line style of Mean lines */
+ void setMeanLineStyle(Qt::PenStyle __value);
+ /*! \brief get the line style of Mean lines */
+ Qt::PenStyle getMeanLineStyle() const;
+ /** \brief sets the dash offset for a custom dash style of Mean lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
+ */
+ void setMeanLineDashOffset(qreal offset);
+ /** \brief returns the dash offset for a custom dash style of Mean lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashOffset
+ */
+ qreal getMeanLineDashOffset() const;
+ /** \brief sets the dash pattern for a custom dash style of Mean lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
+ */
+ void setMeanLineDashPattern(const QVector &pattern);
+ /** \brief gets the dash pattern for a custom dash style of Mean lines
+ * \see https://doc.qt.io/qt-5/qpen.html#setDashPattern
+ */
+ QVector getMeanLineDashPattern() const;
+ /** \brief set the type of the symbol for the mean */
+ void setMeanSymbolType(JKQTPGraphSymbols __value);
+ /** \brief get the type of the symbol for the mean */
+ JKQTPGraphSymbols getMeanSymbolType() const;
+
+ /** \brief set the size (=diameter in pt) of the symbol for the mean (in pt) */
+ void setMeanSize(double __value);
+ /** \brief get the size (=diameter in pt) of the symbol for the mean (in pt) */
+ double getMeanSize() const;
+
+ /** \brief set the color of the symbol for the mean, or mean line */
+ void setMeanColor(const QColor & __value);
+ /** \brief set the color of the symbol for the mean, or mean line */
+ QColor getMeanColor() const;
+
+ /** \brief set the color of filling of the symbol for the mean */
+ void setMeanFillColor(const QColor & __value);
+ /** \brief set the color of filling of the symbol for the mean */
+ QColor getMeanFillColor() const;
+
+ /** \brief set the line width of the symbol for the mean outline, or mean line (in pt) */
+ void setMeanLineWidth(double __value);
+ /** \brief get the line width of the symbol for the mean outline, or mean line (in pt) */
+ double getMeanLineWidth() const;
+
+ /** \brief constructs a QPen from the line styling properties to draw the mean line */
+ QPen getMeanLinePen(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) const;
+ /** \brief constructs a QPen from the line styling properties to draw the mean symbol */
+ QPen getMeanSymbolPen(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) const;
+ /** \brief constructs a QPen from the line styling properties */
+ QBrush getMeanSymbolBrush(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) const;
+
+ /*! \brief set the color of the graph (colors all elements, based on the given color \a c )*/
+ void setBoxplotColor(QColor c, JKQTBasePlotter *parent);
+
+ /*! \brief set the color of the graph (colors all elements, based on the given color \a c , sets background colors from \a bc )*/
+ void setBoxplotColor(QColor c, QColor bc, JKQTBasePlotter *parent);
+
+
+ protected:
+ /*! \brief plot a symbol at location x,y (in painter coordinates), using the current style
+
+ \param parent parent JKQTBasePlotter of the graph that uses this mix-in (used e.g. for line-width transformation)
+ \param painter the QPainter to draw to
+ \param x x-coordinate of the symbol center
+ \param y y-coordinate of the symbol center
+ */
+ void plotStyledMeanSymbol(JKQTBasePlotter* parent, JKQTPEnhancedPainter &painter, double x, double y) const;
+ /** \brief draws a vertical boxplot, with all coordinates/sizes given in coordinates of the given painter,
+ * using the style properties declared in this class. Provide a parameter with \c JKQTP_NAN of you
+ * don't want it to be drawn, or don't know its value
+ *
+ * \param parent parent JKQTBasePlotter of the graph that uses this mix-in (used e.g. for line-width transformation)
+ * \param painter the QPainter to draw to
+ * \param xp x-coordinate of the boxplot center
+ * \param xpleft x-coordinate of the boxplot box left edge
+ * \param xpright x-coordinate of the boxplot box right edge
+ * \param minp y-coordinate of the minimum (lower whisker)
+ * \param q25p y-coordinate of the 25% quartile (lower box border)
+ * \param medianp y-coordinate the median
+ * \param q75p y-coordinate of the 75% quartile (upper box border)
+ * \param maxp y-coordinate of the maximum (upper whisker)
+ * \param meanp y-coordinate of the mean (symbol or line)
+ * \param notchLowerp y-coordinate of the lower (near \a qe5p ) end of the notch interval
+ * \param notchUpperp y-coordinate of the upper (near \a q75p ) end of the notch interval
+ */
+ void plotVerticalBoxplot(JKQTBasePlotter* parent, JKQTPEnhancedPainter &painter, double xp, double xpleft, double xpright, double minp, double q25p, double medianp, double q75p, double maxp, double meanp=JKQTP_NAN, double notchLowerp=JKQTP_NAN, double notchUpperp=JKQTP_NAN) const;
+
+ /** \brief draws a horizontal boxplot, with all coordinates/sizes given in coordinates of the given painter,
+ * using the style properties declared in this class. Provide a parameter with \c JKQTP_NAN of you
+ * don't want it to be drawn, or don't know its value
+ *
+ * \param parent parent JKQTBasePlotter of the graph that uses this mix-in (used e.g. for line-width transformation)
+ * \param painter the QPainter to draw to
+ * \param yp y-coordinate of the boxplot center
+ * \param ypbottom y-coordinate of the boxplot box bottom edge
+ * \param yptop y-coordinate of the boxplot box top edge
+ * \param minp x-coordinate of the minimum (lower whisker)
+ * \param q25p x-coordinate of the 25% quartile (lower box border)
+ * \param medianp x-coordinate the median
+ * \param q75p x-coordinate of the 75% quartile (upper box border)
+ * \param maxp x-coordinate of the maximum (upper whisker)
+ * \param meanp x-coordinate of the mean (symbol or line)
+ * \param notchLowerp x-coordinate of the lower (near \a qe5p ) end of the notch interval
+ * \param notchUpperp x-coordinate of the upper (near \a q75p ) end of the notch interval
+ */
+ void plotHorizontalBoxplot(JKQTBasePlotter* parent, JKQTPEnhancedPainter &painter, double yp, double ypbottom, double yptop, double minp, double q25p, double medianp, double q75p, double maxp, double meanp=JKQTP_NAN, double notchLowerp=JKQTP_NAN, double notchUpperp=JKQTP_NAN) const;
+
+ /** \brief draw a small, stylized, vertical symbol into \a rect that symbolizes a boxplot, e.g. in a plot legend */
+ void plotVerticalKeyMarker(JKQTBasePlotter* parent, JKQTPEnhancedPainter &painter, const QRectF& rect);
+
+ /** \brief draw a small, stylized, horizontal symbol into \a rect that symbolizes a boxplot, e.g. in a plot legend */
+ void plotHorizontalKeyMarker(JKQTBasePlotter* parent, JKQTPEnhancedPainter &painter, const QRectF& rect);
+ private:
+ /** \brief which symbol to use for the datapoints */
+ JKQTPGraphSymbols m_meanSymbolType;
+ /** \brief size (diameter in pt) of the symbol for the data points, given in pt */
+ double m_meanSymbolSize;
+ /** \brief outline color of the symbol or line pen of the mean-line */
+ QPen m_meanSymbolLinePen;
+ /** \brief color of the symbol filling */
+ QColor m_meanSymbolFillColor;
+ /** \brief width (in pt) of the lines used to plot the symbol for the data points, given in pt */
+ double m_meanSymbolLineWidth;
+ /** \brief line style of the whisker lines */
+ QPen m_whiskerLinePen;
+ /** \brief line width (in pt) of the whisker lines */
+ double whiskerLineWidth;
+ /** \brief line style of the whisker cap lines */
+ QPen m_whiskerCapLinePen;
+ /** \brief line width (in pt) of the whisker cap lines */
+ double whiskerCapLineWidth;
+ /** \brief line style of the median lines */
+ QPen m_medianLinePen;
+ /** \brief line width (in pt) of the median lines */
+ double medianLineWidth;
+ /** \brief width of box in pt.
+ *
+ * \note If several boxplots are drawn, the width is typically calculated,
+ * based on a relative width and the position distances, see JKQTPBoxplotVerticalGraph::boxWidthRelative */
+ double boxWidthAbsolute;
+ /** \brief width of the whiskers, relative to the box width (default: 0.5) */
+ double relativeWhiskerWidth;
+ /** \brief single-sided indention of the notch (if any), relative to the box width (default: 0.25) */
+ double relativeNotchIndent;
+
+ /** \brief specifies how to draw the mean (as a line of as a symbol, specified by the function in JKQTPGraphSymbolStyleMixin) */
+ MeanMode meanMode;
+ /** \brief enables/disables drawing of the actual box of the boxplot (\c false leads to Tufte Style boxplots ) */
+ bool drawBox;
+};
+
+
+
+
+
+#endif // jkqtpgraphsboxplotstylingmixins_H
diff --git a/lib/jkqtplottertools/jkqtptools.h b/lib/jkqtplottertools/jkqtptools.h
index 6e2d061f4e..2429e5c650 100644
--- a/lib/jkqtplottertools/jkqtptools.h
+++ b/lib/jkqtplottertools/jkqtptools.h
@@ -75,6 +75,20 @@
class JKQTPEnhancedPainter; // forward
class JKQTBasePlotter; // forward declaration
+/** \brief double-value NotANumber
+ * \ingroup jkqtptools_math
+ */
+#define JKQTP_DOUBLE_NAN (std::numeric_limits::signaling_NaN())
+
+/** \brief float-value NotANumber
+ * \ingroup jkqtptools_math
+ */
+#define JKQTP_FLOAT_NAN (std::numeric_limits::signaling_NaN())
+
+/** \brief double-value NotANumber
+ * \ingroup jkqtptools_math
+ */
+#define JKQTP_NAN JKQTP_DOUBLE_NAN
/** \brief C++11 finally construct
@@ -110,7 +124,7 @@ private:
};
/** \brief C++11 finally construct
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_math
* \see JKQTPFinalAct
*/
template
@@ -120,7 +134,7 @@ inline JKQTPFinalAct JKQTPFinally(const F& f) noexcept
}
/** \brief C++11 finally construct
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_math
* \see JKQTPFinalAct
*/
template
@@ -150,13 +164,13 @@ enum JKQTPUserActionMarkerType {
/** \brief convert a JKQTPUserActionMarkerType to a QString
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see String2JKQTPUserActionMarkerType(), JKQTPUserActionMarkerType
*/
JKQTP_LIB_EXPORT QString JKQTPUserActionMarkerType2String(JKQTPUserActionMarkerType act);
/** \brief convert a QString (created by JKQTPUserActionMarkerType2String() ) to JKQTPUserActionMarkerType
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see JKQTPUserActionMarkerType2String(), JKQTPUserActionMarkerType
*/
@@ -184,13 +198,13 @@ enum JKQTPMouseDragActions {
/** \brief convert a JKQTPMouseDragActions to a QString
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see String2JKQTPMouseDragActions(), JKQTPMouseDragActions
*/
JKQTP_LIB_EXPORT QString JKQTPMouseDragActions2String(JKQTPMouseDragActions act);
/** \brief convert a QString (created by JKQTPMouseDragActions2String() ) to JKQTPMouseDragActions
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see JKQTPMouseDragActions2String(), JKQTPMouseDragActions
*/
@@ -208,13 +222,13 @@ enum JKQTPMouseDoubleClickActions {
};
/** \brief convert a JKQTPMouseDoubleClickActions to a QString
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see String2JKQTPMouseDoubleClickActions(), JKQTPMouseDoubleClickActions
*/
JKQTP_LIB_EXPORT QString JKQTPMouseDoubleClickActions2String(JKQTPMouseDoubleClickActions act);
/** \brief convert a QString (created by JKQTPMouseDoubleClickActions2String() ) to JKQTPMouseDoubleClickActions
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see JKQTPMouseDoubleClickActions2String(), JKQTPMouseDoubleClickActions
*/
@@ -229,13 +243,13 @@ enum JKQTPMouseWheelActions {
};
/** \brief convert a JKQTPMouseWheelActions to a QString
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see String2JKQTPMouseWheelActions(), JKQTPMouseWheelActions
*/
JKQTP_LIB_EXPORT QString JKQTPMouseWheelActions2String(JKQTPMouseWheelActions act);
/** \brief convert a QString (created by JKQTPMouseWheelActions2String() ) to JKQTPMouseWheelActions
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see JKQTPMouseWheelActions2String(), JKQTPMouseWheelActions
*/
@@ -252,13 +266,13 @@ enum JKQTPContextMenuModes {
};
/** \brief convert a JKQTPContextMenuModes to a QString
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see String2JKQTPContextMenuModes(), JKQTPContextMenuModes
*/
JKQTP_LIB_EXPORT QString JKQTPContextMenuModes2String(JKQTPContextMenuModes act);
/** \brief convert a QString (created by JKQTPContextMenuModes2String() ) to JKQTPContextMenuModes
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see JKQTPContextMenuModes2String(), JKQTPContextMenuModes
*/
@@ -274,21 +288,21 @@ typedef QHash, JKQTPMouseDoubleClic
typedef JKQTPMouseDoubleClickActionsHashMap::const_iterator JKQTPMouseDoubleClickActionsHashMapIterator;
/** \brief converts a QT::PenStyle into a string
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString jkqtp_QPenStyle2String(Qt::PenStyle style);
/** \brief converts a QString into a Qt::PenStyle
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT Qt::PenStyle jkqtp_String2QPenStyle(const QString& style);
/** \brief converts a QT::BrushStyle into a string
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString jkqtp_QBrushStyle2String(Qt::BrushStyle style);
/** \brief converts a QString into a Qt::BrushStyle
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT Qt::BrushStyle jkqtp_String2QBrushStyle(const QString& style);
@@ -312,14 +326,14 @@ enum JKQTPColorDerivationMode {
};
/** \brief use a JKQTPColorDerivationMode to derive a color from \a col as specified
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_drawing
*
* \see JKQTPColorDerivationMode
*/
JKQTP_LIB_EXPORT QColor JKQTPGetDerivedColor(JKQTPColorDerivationMode mode, const QColor& col);
/** \brief construct a QColor, based on the given \a color, but with alpha set to the specified value \a alphaF
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_drawing
* \see QColorWithAlpha()
*/
inline QColor QColorWithAlphaF(const QColor& color, qreal alphaF) {
@@ -329,7 +343,7 @@ inline QColor QColorWithAlphaF(const QColor& color, qreal alphaF) {
}
/** \brief construct a QColor, based on the given \a color, but with alpha set to the specified value \a alpha
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_drawing
* \see QColorWithAlphaF()
*/
inline QColor QColorWithAlpha(const QColor& color, int alpha) {
@@ -339,13 +353,13 @@ inline QColor QColorWithAlpha(const QColor& color, int alpha) {
}
/** \brief convert a JKQTPColorDerivationMode to a QString
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see String2JKQTPColorDerivationMode(), JKQTPColorDerivationMode
*/
JKQTP_LIB_EXPORT QString JKQTPColorDerivationMode2String(JKQTPColorDerivationMode mode);
/** \brief convert a QString (created by JKQTPColorDerivationMode2String() ) to JKQTPColorDerivationMode
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*
* \see JKQTPColorDerivationMode2String(), JKQTPColorDerivationMode
*/
@@ -368,34 +382,34 @@ enum JKQTPCADrawMode {
};
/** \brief determines whether JKQTPCADrawMode has the line
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT bool JKQTPCADrawModeHasLine(JKQTPCADrawMode pos);
/** \brief determines whether JKQTPCADrawMode has ticks
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT bool JKQTPCADrawModeHasTicks(JKQTPCADrawMode pos);
/** \brief determines whether JKQTPCADrawMode has tick labels
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT bool JKQTPCADrawModeHasTickLabels(JKQTPCADrawMode pos);
/** \brief determines whether JKQTPCADrawMode has the axis label
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT bool JKQTPCADrawModeHasAxisLabel(JKQTPCADrawMode pos);
/** \brief converts a JKQTPCADrawMode variable into a human-readable string
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString JKQTPCADrawMode2String(JKQTPCADrawMode pos);
/** \brief converts a string into a JKQTPCADrawMode
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT JKQTPCADrawMode String2JKQTPCADrawMode(const QString& pos);
@@ -422,23 +436,23 @@ enum JKQTPLabelTickMode {
};
/** \brief converts a JKQTPLabelTickMode variable into a human-readable string
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString JKQTPLabelTickMode2String(JKQTPLabelTickMode pos);
/** \brief converts a string into a JKQTPLabelTickMode
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT JKQTPLabelTickMode String2JKQTPLabelTickMode(const QString& pos);
/** \brief converts a JKQTPCALabelType variable into a human-readable string
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString JKQTPCALabelType2String(JKQTPCALabelType pos);
/** \brief converts a string into a JKQTPCALabelType
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT JKQTPCALabelType String2JKQTPCALabelType(const QString& pos);
@@ -453,12 +467,12 @@ enum JKQTPLabelPosition {
/** \brief converts a JKQTPLabelPosition variable into a human-readable string
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString JKQTPLabelPosition2String(JKQTPLabelPosition pos);
/** \brief converts a string into a JKQTPLabelPosition
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT JKQTPLabelPosition String2JKQTPLabelPosition(const QString& pos);
@@ -482,12 +496,12 @@ enum JKQTPKeyPosition {
/** \brief converts a JKQTPLabelPosition variable into a human-readable string
- * \ingroup jkqtptools
+ * \ingroup jkqjkqtptools_stringtptools
*/
JKQTP_LIB_EXPORT QString JKQTPKeyPosition2String(JKQTPKeyPosition pos);
/** \brief converts a string into a JKQTPLabelPosition
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT JKQTPKeyPosition String2JKQTPKeyPosition(const QString& pos);
@@ -502,12 +516,12 @@ enum JKQTPKeyLayout {
/** \brief converts a JKQTPKeyLayout variable into a human-readable string
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString JKQTPKeyLayout2String(JKQTPKeyLayout pos);
/** \brief converts a String into a JKQTPKeyLayout
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT JKQTPKeyLayout String2JKQTPKeyLayout(const QString& pos);
@@ -549,12 +563,12 @@ enum JKQTPErrorPlotstyle {
/** \brief converts a JKQTPErrorPlotstyle variable into a human-readable string
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString JKQTPErrorPlotstyle2String(JKQTPErrorPlotstyle pos);
/** \brief converts a String into a JKQTPErrorPlotstyle
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT JKQTPErrorPlotstyle String2JKQTPErrorPlotstyle(const QString& pos);
@@ -606,22 +620,22 @@ enum JKQTPGraphSymbols {
};
/** \brief converts a JKQTPGraphSymbols variable into a identifier string
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString JKQTPGraphSymbols2String(JKQTPGraphSymbols pos);
/** \brief converts a JKQTPGraphSymbols variable into a human-readable string
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT QString JKQTPGraphSymbols2NameString(JKQTPGraphSymbols pos);
/** \brief converts a String into a JKQTPGraphSymbols
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
JKQTP_LIB_EXPORT JKQTPGraphSymbols String2JKQTPGraphSymbols(const QString& pos);
/** \brief convert a double to a string, using the loacle "C"
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
inline QString JKQTPCDoubleToQString(double value) {
QLocale loc=QLocale::c();
@@ -630,7 +644,7 @@ inline QString JKQTPCDoubleToQString(double value) {
}
/** \brief convert a double to a string
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_string
*/
inline QString JKQTPDoubleToQString(double value, int prec = 10, char f = 'g', QChar decimalSeparator='.') {
QLocale loc=QLocale::c();
@@ -645,7 +659,7 @@ inline QString JKQTPDoubleToQString(double value, int prec = 10, char f = 'g', Q
/** \brief rotate a rectangle by given angle (rotates all points around the center of the rectangle and returns it as a QPolygonF)
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_math
*/
JKQTP_LIB_EXPORT QPolygonF jkqtpRotateRect(QRectF r, double angle);
@@ -867,7 +881,7 @@ JKQTP_LIB_EXPORT std::string jkqtp_floattohtmlstr(double data, int past_comma=5,
JKQTP_LIB_EXPORT std::string jkqtp_chartostr(char data);
/** \brief wandelt einen Datentyp in einen double um, wird von JKQTPDatastore zur Wandlung benutzt
- * \ingroup jkqtptools
+ * \ingroup jkqtptools_math
*
* Diese Funktion nutzt per default static_cast(), kann aber für spezielle Datentypen überschrieben werden, etwa für bool
*/
@@ -879,7 +893,7 @@ inline constexpr double jkqtp_todouble(const T& d) {
/** \brief wandelt einen boolean in einen double um, wird von JKQTPDatastore zur Wandlung benutzt,
* Spezialisierung für bool (true -> 1.0, false -> 0.0)
- * \ingroup jkqtptools */
+ * \ingroup jkqtptools_math */
template<>
inline constexpr double jkqtp_todouble(const bool& d) {
return static_cast((d)?1.0:0.0);
@@ -912,7 +926,8 @@ JKQTP_LIB_EXPORT QString JKQTPSpecialLineType2String(JKQTPSpecialLineType pos);
*/
JKQTP_LIB_EXPORT JKQTPSpecialLineType String2JKQTPSpecialLineType(const QString& pos);
-/** \brief round a double using round() and convert it to a specified type T (static_cast!) */
+/** \brief round a double using round() and convert it to a specified type T (static_cast!)
+ * \ingroup jkqtptools_math */
template
inline T jkqtp_roundTo(const double& v) {
return static_cast(round(v));
@@ -920,19 +935,22 @@ inline T jkqtp_roundTo(const double& v) {
-/** \brief compare two floats \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality */
+/** \brief compare two floats \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
+ * \ingroup jkqtptools_math */
inline bool jkqtp_approximatelyEqual(float a, float b, float epsilon=2.0*std::numeric_limits::epsilon())
{
return fabsf(a - b) <= epsilon;
}
-/** \brief compare two doubles \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality */
+/** \brief compare two doubles \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
+ * \ingroup jkqtptools_math */
inline bool jkqtp_approximatelyEqual(double a, double b, double epsilon=2.0*std::numeric_limits::epsilon())
{
return fabs(a - b) <= epsilon;
}
-/** \brief returns the quare of the value \a v, i.e. \c v*v */
+/** \brief returns the quare of the value \a v, i.e. \c v*v
+ * \ingroup jkqtptools_math */
template
inline T jkqtp_sqr(const T& v) {
return v*v;
diff --git a/screenshots/jkqtplotter_simpletest_boxplot.png b/screenshots/jkqtplotter_simpletest_boxplot.png
index 55f844c8f4..2786aa119c 100644
Binary files a/screenshots/jkqtplotter_simpletest_boxplot.png and b/screenshots/jkqtplotter_simpletest_boxplot.png differ
diff --git a/screenshots/jkqtplotter_simpletest_boxplot_small.png b/screenshots/jkqtplotter_simpletest_boxplot_small.png
index 11e72a4e40..c7d5ba1b29 100644
Binary files a/screenshots/jkqtplotter_simpletest_boxplot_small.png and b/screenshots/jkqtplotter_simpletest_boxplot_small.png differ
diff --git a/screenshots/plot_boxplothorizontalelement.png b/screenshots/plot_boxplothorizontalelement.png
deleted file mode 100644
index 6833d4e9b3..0000000000
Binary files a/screenshots/plot_boxplothorizontalelement.png and /dev/null differ
diff --git a/screenshots/plot_boxplotverticalelement.png b/screenshots/plot_boxplotverticalelement.png
deleted file mode 100644
index 03fdaa7b76..0000000000
Binary files a/screenshots/plot_boxplotverticalelement.png and /dev/null differ
diff --git a/screenshots/test_distributionplot.png b/screenshots/test_distributionplot.png
index af6ca8f1a4..8892c00324 100644
Binary files a/screenshots/test_distributionplot.png and b/screenshots/test_distributionplot.png differ
diff --git a/screenshots/test_distributionplot_small.png b/screenshots/test_distributionplot_small.png
index a3ec9440eb..7199186b9a 100644
Binary files a/screenshots/test_distributionplot_small.png and b/screenshots/test_distributionplot_small.png differ
diff --git a/screenshots/test_styledboxplot.png b/screenshots/test_styledboxplot.png
new file mode 100644
index 0000000000..d20e77b4d4
Binary files /dev/null and b/screenshots/test_styledboxplot.png differ
diff --git a/screenshots/test_styledboxplot_small.png b/screenshots/test_styledboxplot_small.png
new file mode 100644
index 0000000000..f9e3854c1c
Binary files /dev/null and b/screenshots/test_styledboxplot_small.png differ
|