new: improved styling options of boxplots (options to style many more elements of the plot), moved JKQTPGraphBoxplotStyleMixin to its own file

new: notched boxplots
new: example for styling boxplots
This commit is contained in:
jkriege2 2019-05-11 15:56:11 +02:00
parent 477f48be70
commit 20352285ca
36 changed files with 1979 additions and 869 deletions

View File

@ -98,5 +98,6 @@ defineTest(addTest) {
addTest(multiplot)
addTest(user_interaction)
addTest(styling)
#addTest(distributionplot)
addTest(styledboxplot)
addTest(distributionplot)

View File

@ -78,6 +78,12 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
<tr><td> \image html jkqtplotter_simpletest_advancedlineandfillstyling_small.png
<td> \subpage JKQTPlotterAdvancedLineAndFillStyling
<td> `JKQTPXYLineGraph`, `JKQTPSpecialLineHorizontalGraph` and `JKQTPBarVerticalGraph` <br> C++ vector of data <br> advanced line styling and filling
<tr><td> \image html test_styledboxplot_small.png
<td> \subpage JKQTPlotterBoxplotStyling
<td> Modifying different Aspects of the Styling of boxplots
<tr><td> \image html test_styling_small.png
<td> \subpage JKQTPlotterStyling
<td> Modifying different Aspects of the Styling of JKQTPlotter
</table>

View File

@ -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

View File

@ -41,6 +41,8 @@ Changes, compared to \ref WHATSNEW_V2018_08 "v2018.08" include:
<li> new: JKQTPXYParametrizedScatterGraph: added functors to transform column values into symbol type+size and line-width to give even more control </li>
<li> 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 </li>
<li> new: user-interaction tool that measures distances and angles when mouse is dragged, while mouse button is pressed) \see jkqtpmdaRuler </li>
<li> new: advanced styling options for boxplots + example for the styling: \ref JKQTPlotterBoxplotStyling </li>
<li> new: notched boxplots </li>
<li> changed: removed old selection-code and replaced by general highlighting feature </li>
<li> changed: JKQTPStepHorizontalGraph has been renamed to JKQTPSpecialLineHorizontalGraph (vertical variants also) and have gained additional features (baseline for filling and drawing of symbols) </li>
<li> changed: filled curve graphs (e.g. JKQTPSpecialLineHorizontalGraph) are now merely a specializedly initialized JKQTPSpecialLineHorizontalGraph </li>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -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` <br> C++ vector of data <br> logarithmic axes and styling <br> plot line styles <br> internal LaTeX parser <br> add commenting text to a graph |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_dateaxes_small.png) <br> ![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_dateaxes_dates_small.png) <br> ![](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` <br> C++ vector of data <br> date/time axes <br> plot min/max range graph <br> internal LaTeX parser <br> 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` <br> C++ vector of data <br> 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` <br> C++ vector of data <br> 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

View File

@ -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)

View File

@ -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:

View File

@ -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);

View File

@ -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<double>(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);

View File

@ -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<double>(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();
}

View File

@ -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)

View File

@ -0,0 +1,214 @@
/** \example test_styledboxplot.cpp
* Shows how to style different aspects of boxplots.
*
* \ref JKQTPlotterBoxplotStyling
*/
#include <QApplication>
#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();
}

View File

@ -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")

View File

@ -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

View File

@ -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 \

View File

@ -336,7 +336,7 @@ int JKQTPDatastore::getColumnNum(const QString& name) {
QMapIterator<size_t, JKQTPColumn> it(columns);
while (it.hasNext()) {
it.next();
if (it.value().getName()==name) return it.key();
if (it.value().getName()==name) return static_cast<int>(it.key());
}
return -1;
}
@ -347,21 +347,22 @@ int JKQTPDatastore::ensureColumnNum(const QString& name) {
QMapIterator<size_t, JKQTPColumn> it(columns);
while (it.hasNext()) {
it.next();
if (it.value().getName()==name) return it.key();
if (it.value().getName()==name) return static_cast<int>(it.key());
}
return addColumn(0, name);
return static_cast<int>(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<size_t>(i));
}
////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -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<size_t>(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<size_t>(column), static_cast<size_t>(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<size_t>(column), static_cast<size_t>(row));
}
////////////////////////////////////////////////////////////////////////////////////////////////
inline double JKQTPDatastore::get(size_t column, int row) const {
if (row<0) return JKQTP_NAN;
return get(static_cast<size_t>(column), static_cast<size_t>(row));
}

View File

@ -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; i<m_hitTestData.count(); i++) {
@ -227,7 +227,7 @@ double JKQTPPlotElement::hitTest(const QPointF & posSystem, QPointF* closestSpot
if (label) *label=m_hitTestData[closest].label;
return closedist;
} else {
return nan("");
return JKQTP_NAN;
}
}
@ -405,7 +405,7 @@ void JKQTPXYGraph::setDataSortOrder(int __value) {
double JKQTPXYGraph::hitTest(const QPointF &posSystem, QPointF *closestSpotSystem, QString *label, HitTestMode mode) const
{
if (parent==nullptr) return nan("");
if (parent==nullptr) return JKQTP_NAN;
// check base-class implementation and use it, if it returns a vaid value
const double baseclassResult=JKQTPPlotElement::hitTest(posSystem, closestSpotSystem, label, mode);
@ -414,12 +414,12 @@ double JKQTPXYGraph::hitTest(const QPointF &posSystem, QPointF *closestSpotSyste
JKQTPDatastore* datastore=parent->getDatastore();
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; i<imax; i++) {
@ -446,7 +446,7 @@ double JKQTPXYGraph::hitTest(const QPointF &posSystem, QPointF *closestSpotSyste
if (closestSpotSystem) *closestSpotSystem=closestPos;
return closedist;
} else {
return nan("");
return JKQTP_NAN;
}
}

View File

@ -183,7 +183,7 @@ class JKQTP_LIB_EXPORT JKQTPPlotElement: public QObject {
* \see hitTest()
*/
struct HitTestLocation {
inline HitTestLocation(): pos(nan(""), nan("")), index(-1), label("") {}
inline HitTestLocation(): pos(JKQTP_NAN, JKQTP_NAN), index(-1), label("") {}
inline HitTestLocation(double x_, double y_, const QString& label_): pos(x_,y_), index(-1), label(label_) {}
inline HitTestLocation(const QPointF& pos_, const QString& label_): pos(pos_), index(-1), label(label_) {}
inline HitTestLocation(double x_, double y_, int index_, const QString& label_): pos(x_,y_), index(index_), label(label_) {}

View File

@ -221,6 +221,7 @@ class JKQTP_LIB_EXPORT JKQTPGraphSymbolStyleMixin {
QBrush getSymbolBrush(JKQTPEnhancedPainter &painter, JKQTBasePlotter* parent) 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 <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> 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 <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> 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 <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> 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 <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> to draw to
\param x x-coordinate of the symbol center
\param y y-coordinate of the symbol center

File diff suppressed because it is too large Load Diff

View File

@ -25,6 +25,7 @@
#include "jkqtplottertools/jkqtp_imexport.h"
#include "jkqtplottertools/jkqtpimagetools.h"
#include "jkqtplotter/jkqtpgraphsbase.h"
#include "jkqtplotter/jkqtpgraphsboxplotstylingmixins.h"
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
#ifndef jkqtpgraphsboxplot_H
@ -34,178 +35,7 @@
/*! \brief Styling Mix-In for Boxplots
\ingroup jkqtplotter_basegraphs_stylemixins
*/
class JKQTP_LIB_EXPORT JKQTPGraphBoxplotStyleMixin: public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin, public JKQTPGraphSymbolStyleMixin {
Q_GADGET
public:
/** \brief class constructor */
JKQTPGraphBoxplotStyleMixin();
void initBoxplotStyle(JKQTBasePlotter* parent, int &parentPlotStyle);
/*! \copydoc boxWidth
\see see boxWidth for details */
void setBoxWidth(double __value);
/*! \copydoc boxWidth
\see see boxWidth for details */
double getBoxWidth() 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<qreal> &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<qreal> 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<qreal> &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<qreal> 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 <a href="http://en.wikipedia.org/wiki/Box_plot">boxplots</a>
/*! \brief This implements vertical <a href="http://en.wikipedia.org/wiki/Box_plot">boxplots</a>, 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: <BLOCKQUOTE>\copydoc percentile75Column </BLOCKQUOTE>
\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: <BLOCKQUOTE>\copydoc medianConfidenceColumn </BLOCKQUOTE>
\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 <a href="http://en.wikipedia.org/wiki/Box_plot">boxplots</a>
/*! \brief This implements horizontal <a href="http://en.wikipedia.org/wiki/Box_plot">boxplots</a>, 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 <a href="http://en.wikipedia.org/wiki/Box_plot">boxplot</a> as a "geometric element",
/*! \brief This implements a single vertical <a href="http://en.wikipedia.org/wiki/Box_plot">(notched) boxplot</a> 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 <a href="http://en.wikipedia.org/wiki/Box_plot">boxplot</a> where the data is directly given to the
/*! \brief This implements a horizontal <a href="http://en.wikipedia.org/wiki/Box_plot">(notched) boxplot</a> where the data is directly given to the
object and not stored in a column, as in JKQTPBoxplotVerticalGraph
\ingroup jkqtplotter_statgraphs
\ingroup jkqtplotter_geoplots

View File

@ -0,0 +1,785 @@
/*
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
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 <http://www.gnu.org/licenses/>.
*/
#include "jkqtplotter/jkqtpgraphsboxplotstylingmixins.h"
#include "jkqtplotter/jkqtpbaseplotter.h"
#include <stdlib.h>
#include <QDebug>
#include <iostream>
#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<qreal> &pattern)
{
m_meanSymbolLinePen.setDashPattern(pattern);
m_meanSymbolLinePen.setStyle(Qt::CustomDashLine);
}
QVector<qreal> 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<qreal> &pattern)
{
m_medianLinePen.setDashPattern(pattern);
m_medianLinePen.setStyle(Qt::CustomDashLine);
}
QVector<qreal> 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<qreal> &pattern)
{
m_whiskerLinePen.setDashPattern(pattern);
m_whiskerLinePen.setStyle(Qt::CustomDashLine);
}
QVector<qreal> 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<qreal> &pattern)
{
m_whiskerCapLinePen.setDashPattern(pattern);
m_whiskerCapLinePen.setStyle(Qt::CustomDashLine);
}
QVector<qreal> 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<<QPointF(xpleft, q75p)<<QPointF(xpleft, notchUpperp)<<QPointF(xpleft+wl*getRelativeNotchIndent(), medianp)<<QPointF(xpleft, notchLowerp)<<QPointF(xpleft, q25p)
<<QPointF(xpright, q25p)<<QPointF(xpright, notchLowerp)<<QPointF(xpright-wr*getRelativeNotchIndent(), medianp)<<QPointF(xpright, notchUpperp)<<QPointF(xpright, q75p)
<<QPointF(xpleft, q75p);
medianMin=xpleft+wl*getRelativeNotchIndent();
medianMax=xpright-wr*getRelativeNotchIndent();
} else {
// simple rectangle
poly<<QPointF(xpleft, q75p)<<QPointF(xpright, q75p)<<QPointF(xpright, q25p)<<QPointF(xpleft, q25p)<<QPointF(xpleft, q75p);
}
painter.drawPolygon(poly);
}
}
// draw median
if (JKQTPIsOKFloat(medianp)) {
painter.setBrush(Qt::NoBrush);
painter.setPen(getMedianPen(painter, parent));
painter.drawLine(QLineF(medianMin, medianp, medianMax, medianp));
}
// draw mean
if (JKQTPIsOKFloat(meanp)) {
painter.setBrush(Qt::NoBrush);
if (getMeanMode()==MeanAsSymbol) {
plotStyledMeanSymbol(parent, painter,xp,meanp);
} else {
painter.setPen(getMeanLinePen(painter, parent));
painter.drawLine(QLineF(xpleft, meanp, xpright, meanp));
}
}
}
}
void JKQTPGraphBoxplotStyleMixin::plotHorizontalBoxplot(JKQTBasePlotter *parent, JKQTPEnhancedPainter &painter, double yp, double ypbottom, double yptop, double minp, double q25p, double medianp, double q75p, double maxp, double meanp, double notchLowerp, double notchUpperp) const
{
if (JKQTPIsOKFloat(yp) ) {
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 wbot=fabs(ypbottom-yp);
const double wtop=fabs(yptop-yp);
const double xbottomWhisker=yp+wbot*getRelativeWhiskerWidth();
const double xptopWhisker=yp-wtop*getRelativeWhiskerWidth();
// whisker lines
painter.setPen(getWhiskerPen(painter, parent));
if (JKQTPIsOKFloat(minp) && JKQTPIsOKFloat(minstop)) {
painter.drawLine(QLineF(minp, yp, minstop, yp));
}
if (JKQTPIsOKFloat(maxp) && JKQTPIsOKFloat(maxstop)) {
painter.drawLine(QLineF(maxp, yp, maxstop, yp));
}
// whisker caps
if (JKQTPIsOKFloat(xptopWhisker) && JKQTPIsOKFloat(xbottomWhisker)){
painter.setPen(getWhiskerCapPen(painter, parent));
if (JKQTPIsOKFloat(minp)) {
painter.drawLine(QLineF(minp, xptopWhisker, minp, xbottomWhisker));
}
if (JKQTPIsOKFloat(maxp)) {
painter.drawLine(QLineF(maxp, xptopWhisker, maxp, xbottomWhisker));
}
}
// draw main box
double medianMin=yptop;
double medianMax=ypbottom;
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<<QPointF(q75p, yptop)<<QPointF(notchUpperp, yptop)<<QPointF(medianp, yptop-wtop*getRelativeNotchIndent())<<QPointF(notchLowerp, yptop)<<QPointF(q25p, yptop)
<<QPointF(q25p, ypbottom)<<QPointF(notchLowerp, ypbottom)<<QPointF(medianp, ypbottom+wbot*getRelativeNotchIndent())<<QPointF(notchUpperp, ypbottom)<<QPointF(q75p, ypbottom)
<<QPointF(q75p, yptop);
medianMin=yptop-wtop*getRelativeNotchIndent();
medianMax=ypbottom+wbot*getRelativeNotchIndent();
} else {
// simple rectangle
poly<<QPointF(q75p, yptop)<<QPointF(q75p, ypbottom)<<QPointF(q25p, ypbottom)<<QPointF(q25p, yptop)<<QPointF(q75p, yptop);
}
painter.drawPolygon(poly);
}
}
// draw median
if (JKQTPIsOKFloat(medianp)) {
painter.setBrush(Qt::NoBrush);
painter.setPen(getMedianPen(painter, parent));
painter.drawLine(QLineF(medianp, medianMin, medianp, medianMax));
}
// draw mean
if (JKQTPIsOKFloat(meanp)) {
painter.setBrush(Qt::NoBrush);
if (getMeanMode()==MeanAsSymbol) {
plotStyledMeanSymbol(parent, painter,meanp,yp);
} else {
painter.setPen(getMeanLinePen(painter, parent));
painter.drawLine(QLineF(meanp, yptop, meanp, ypbottom));
}
}
}
}
void JKQTPGraphBoxplotStyleMixin::plotVerticalKeyMarker(JKQTBasePlotter *parent, JKQTPEnhancedPainter &painter, const 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(0.5, p.widthF()));
p.setStyle(Qt::SolidLine);
pw.setWidthF(qMin(0.5, pw.widthF()));
pw.setStyle(Qt::SolidLine);
pm.setWidthF(qMin(0.5, pm.widthF()));
pm.setStyle(Qt::SolidLine);
const double x=rect.left()+rect.width()/2.0;
const double xma=x+rect.width()/2.5;
const double xmi=x-rect.width()/2.5;
const double min=rect.bottom();
const double max=rect.top();
const double median=max+rect.height()/2.0;
const double w=abs(xma-xmi);
const double p25=max+0.75*rect.height();
const double p75=max+0.25*rect.height();
painter.setPen(p);
{
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setBrush(b);
if (getDrawBox()) 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*0.4, max, x+w*0.4, max));
painter.drawLine(QLineF(x-w*0.4, min, x+w*0.4, min));
painter.drawLine(QLineF(x, max, x, p75));
painter.drawLine(QLineF(x, min, x, p25));
}
void JKQTPGraphBoxplotStyleMixin::plotHorizontalKeyMarker(JKQTBasePlotter *parent, JKQTPEnhancedPainter &painter, const QRectF &rect)
{
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.translate(rect.center());
painter.rotate(90);
painter.translate(-1.0*rect.height()/2.0, -1.0*rect.width()/2.0);
plotVerticalKeyMarker(parent, painter, QRectF(0,0,rect.height(),rect.width()));
}

View File

@ -0,0 +1,440 @@
/*
Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
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 <http://www.gnu.org/licenses/>.
*/
#include <QString>
#include <QPainter>
#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<qreal> &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<qreal> 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<qreal> &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<qreal> 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<qreal> &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<qreal> 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<qreal> &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<qreal> 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 <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> 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 <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> 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 <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> 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

View File

@ -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<double>::signaling_NaN())
/** \brief float-value NotANumber
* \ingroup jkqtptools_math
*/
#define JKQTP_FLOAT_NAN (std::numeric_limits<float>::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 <class F>
@ -120,7 +134,7 @@ inline JKQTPFinalAct<F> JKQTPFinally(const F& f) noexcept
}
/** \brief C++11 finally construct
* \ingroup jkqtptools
* \ingroup jkqtptools_math
* \see JKQTPFinalAct
*/
template <class F>
@ -150,13 +164,13 @@ enum JKQTPUserActionMarkerType {
/** \brief convert a JKQTPUserActionMarkerType to a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools
* \ingroup jkqtptools_string
*
* \see String2JKQTPUserActionMarkerType(), JKQTPUserActionMarkerType
*/
JKQTP_LIB_EXPORT QString JKQTPUserActionMarkerType2String(JKQTPUserActionMarkerType act);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (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 <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools
* \ingroup jkqtptools_string
*
* \see String2JKQTPMouseDragActions(), JKQTPMouseDragActions
*/
JKQTP_LIB_EXPORT QString JKQTPMouseDragActions2String(JKQTPMouseDragActions act);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (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 <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools
* \ingroup jkqtptools_string
*
* \see String2JKQTPMouseDoubleClickActions(), JKQTPMouseDoubleClickActions
*/
JKQTP_LIB_EXPORT QString JKQTPMouseDoubleClickActions2String(JKQTPMouseDoubleClickActions act);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (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 <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools
* \ingroup jkqtptools_string
*
* \see String2JKQTPMouseWheelActions(), JKQTPMouseWheelActions
*/
JKQTP_LIB_EXPORT QString JKQTPMouseWheelActions2String(JKQTPMouseWheelActions act);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (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 <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools
* \ingroup jkqtptools_string
*
* \see String2JKQTPContextMenuModes(), JKQTPContextMenuModes
*/
JKQTP_LIB_EXPORT QString JKQTPContextMenuModes2String(JKQTPContextMenuModes act);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (created by JKQTPContextMenuModes2String() ) to JKQTPContextMenuModes
* \ingroup jkqtptools
* \ingroup jkqtptools_string
*
* \see JKQTPContextMenuModes2String(), JKQTPContextMenuModes
*/
@ -274,21 +288,21 @@ typedef QHash<QPair<Qt::MouseButton,Qt::KeyboardModifiers>, 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 <a href="http://doc.qt.io/qt-5/qstring.html">QString</a>
* \ingroup jkqtptools
* \ingroup jkqtptools_string
*
* \see String2JKQTPColorDerivationMode(), JKQTPColorDerivationMode
*/
JKQTP_LIB_EXPORT QString JKQTPColorDerivationMode2String(JKQTPColorDerivationMode mode);
/** \brief convert a <a href="http://doc.qt.io/qt-5/qstring.html">QString</a> (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<double>(), 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<double>((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<typename T>
inline T jkqtp_roundTo(const double& v) {
return static_cast<T>(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<float>::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<double>::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<typename T>
inline T jkqtp_sqr(const T& v) {
return v*v;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB