diff --git a/JKQtPlotterBuildAllExamples.pro b/JKQtPlotterBuildAllExamples.pro index fa171c1678..9a120f9125 100644 --- a/JKQtPlotterBuildAllExamples.pro +++ b/JKQtPlotterBuildAllExamples.pro @@ -75,6 +75,7 @@ addSimpleTest(functionplot) addSimpleTest(geometric) addSimpleTest(ui) addSimpleTest(boxplot) +addSimpleTest(advancedlineandfillstyling) #addSimpleTest(imageplot_nodatastore) #addSimpleTest(rgbimageplot_opencv) #addSimpleTest(imageplot_opencv) diff --git a/doc/dox/examples_and_tutorials.dox b/doc/dox/examples_and_tutorials.dox index 56785145f4..6b33131543 100644 --- a/doc/dox/examples_and_tutorials.dox +++ b/doc/dox/examples_and_tutorials.dox @@ -75,6 +75,9 @@ All test-projects are Qt-projects that use qmake to build. You can load them int \image html jkqtplotter_simpletest_dateaxes_timeaxis_small.png \subpage JKQTPlotterDateTimeAxes `JKQTPXYLineGraph` and `JKQTPFilledVerticalRangeGraph`
C++ vector of data
date/time axes
plot min/max range graph
internal LaTeX parser
data from CSV files + \image html jkqtplotter_simpletest_advancedlineandfillstyling_small.png + \subpage JKQTPlotterAdvancedLineAndFillStyling + `JKQTPXYLineGraph`, `JKQTPSpecialLineHorizontalGraph` and `JKQTPBarVerticalGraph`
C++ vector of data
advanced line styling and filling diff --git a/examples/README.md b/examples/README.md index 650f627ab1..cd226e6c44 100644 --- a/examples/README.md +++ b/examples/README.md @@ -31,6 +31,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int |:-------------:| ------------- | ------------- | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_logaxes_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_logaxes) | [logarithmic axes](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_logaxes) | `JKQTPXYLineGraph` and `JKQTPGeoText`
C++ vector of data
logarithmic axes and styling
plot line styles
internal LaTeX parser
add commenting text to a graph | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_dateaxes_small.png)
![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_dateaxes_dates_small.png)
![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_dateaxes_timeaxis_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_dateaxes) | [date/time axes](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_dateaxes) | `JKQTPXYLineGraph` and `JKQTPFilledVerticalRangeGraph`
C++ vector of data
date/time axes
plot min/max range graph
internal LaTeX parser
data from CSV files | +| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_advancedlineandfillstyling_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_advancedlineandfillstyling) | [logarithmic axes](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_advancedlineandfillstyling) | `JKQTPXYLineGraph`, `JKQTPSpecialLineHorizontalGraph` and `JKQTPBarVerticalGraph`
C++ vector of data
advanced line styling and filling | ## Image data Plots diff --git a/examples/simpletest_advancedlineandfillstyling/README.md b/examples/simpletest_advancedlineandfillstyling/README.md new file mode 100644 index 0000000000..a42dcfc6f2 --- /dev/null +++ b/examples/simpletest_advancedlineandfillstyling/README.md @@ -0,0 +1,99 @@ +# Example (JKQTPlotter): Advanced Line and Fill Styling {#JKQTPlotterAdvancedLineAndFillStyling} +This project (see `./examples/simpletest_advancedlineandfillstyling/`) demonstrates how to use advanced line styling and filling options (e.g. custom dash-styles, gradient, image fills, transparencies, ...) with JKQtPlotter. + +The source code of the main application can be found in [`jkqtplotter_simpletest_advancedlineandfillstyling.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.cpp). + +Initially several data columns are generated and added to the internal datastore. Then several line graphs are added that all use different custom dashes. In addition the third line does not use a single color, but a gradient for coloring: +```.cpp + JKQTPGeoLine* graphL1=new JKQTPGeoLine(&plot, 0, 3, 12, 3.5, Qt::red); + JKQTPGeoLine* graphL2=new JKQTPGeoLine(&plot, 0, 3.8, 12, 4.5, Qt::red); + JKQTPGeoLine* graphL3=new JKQTPGeoLine(&plot, 0, 4.6, 12, 5.5, Qt::red); + + // 5.2 set advanced line style (see also https://doc.qt.io/qt-5/qpen.html#setDashPattern) + // and use a gradient-brush to fill the last (thicker) line + QVector dashes1; + dashes1 << 2 << 2 << 2 << 2 << 4 << 4 << 4 << 4 << 8 << 8 << 8 << 8 ; + graphL1->setLineDashPattern(dashes1); + graphL1->setLineWidth(2); + QVector dashes2; + dashes2 << 1 << 2 << 2 << 2 << 3 << 2 << 4 << 2 << 5 << 2 << 6 << 2 ; + graphL2->setLineDashPattern(dashes2); + graphL2->setLineWidth(2); + QVector dashes3; + dashes3 << 4 << 4 << 4 << 4 << 12 << 4 ; + graphL3->setLineDashPattern(dashes3); + graphL3->setLineWidth(4); + QLinearGradient lineGrad(QPointF(0, 0), QPointF(1, 0)); + lineGrad.setColorAt(0, Qt::red); + lineGrad.setColorAt(1, Qt::green); + lineGrad.setCoordinateMode(QGradient::ObjectBoundingMode); + graphL3->setLineBrush(lineGrad); +``` + +In addition, a `JKQTPSpecialLineHorizontalGraph` is filled using an image `example.bmp` as a texture: +```.cpp + JKQTPSpecialLineHorizontalGraph* graphF=new JKQTPSpecialLineHorizontalGraph(&plot); + + // 5.2 set fill style, using an image, also rotate the images + graphF->setSpecialLineType(JKQTPDirectLine); + graphF->setDrawLine(true); + graphF->setFillTexture(QPixmap(":/example.bmp")); + graphF->setFillTransform(QMatrix(0.5,0,0,0.5,0,0).rotate(45)); + graphF->setFillCurve(true); + graphF->setLineWidth(0.5); +``` + +This texture-filled graph is overlayn by a graph filled with a color gradient that is semi-transparent in some colors: + +```.cpp + JKQTPSpecialLineHorizontalGraph* graphF2=new JKQTPSpecialLineHorizontalGraph(&plot); + + // 5.3 set fill style, using a custom linear gradient, also with changing transparency (alpha) values + graphF2->setSpecialLineType(JKQTPStepCenter); + graphF2->setDrawLine(false); + graphF2->setFillCurve(true); + QLinearGradient linearGrad(QPointF(0, 0), QPointF(1, 1)); + QColor c1(Qt::yellow); + c1.setAlphaF(0.5); + QColor c2(Qt::red); + QColor c3(Qt::blue); + QColor c4(Qt::green); + c4.setAlphaF(0.5); + linearGrad.setColorAt(0, c1); + linearGrad.setColorAt(0.3, c2); + linearGrad.setColorAt(0.7, c3); + linearGrad.setColorAt(1, c4); + linearGrad.setCoordinateMode(QGradient::ObjectMode); + // use this CoordinateMode, so the gradient fills the whole graph area + graphF2->setFillGradient(linearGrad); +``` + +Finally two vertical barcharts with different filling options are added: + +```.cpp + JKQTPBarVerticalGraph* graphBE=new JKQTPBarVerticalGraph(&plot); + JKQTPBarVerticalGraph* graphBF=new JKQTPBarVerticalGraph(&plot); + + // 5.4 fill barcharts with transparencies and make the surrounding line invisible (colored transparent) + QColor c0=QColor("darkgreen").darker(); + c0.setAlphaF(.75); + graphBE->setFillColor(c0); + graphBE->setLineColor(Qt::transparent); + QLinearGradient linearG(QPointF(0, 0), QPointF(0, 1)); + QColor cl11(QColor("darkgreen")); + QColor cl12(Qt::green); + cl12.setAlphaF(0.5); + linearG.setColorAt(0, cl11); + linearG.setColorAt(1, cl12); + linearG.setCoordinateMode(QGradient::ObjectMode); + graphBF->setFillGradient(linearG); + graphBF->setLineColor(Qt::transparent);``` + + + +The result looks like this: + +![jkqtplotter_simpletest_advancedlineandfillstyling](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_advancedlineandfillstyling.png) + + + diff --git a/examples/simpletest_advancedlineandfillstyling/example.bmp b/examples/simpletest_advancedlineandfillstyling/example.bmp new file mode 100644 index 0000000000..276b359c54 Binary files /dev/null and b/examples/simpletest_advancedlineandfillstyling/example.bmp differ diff --git a/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.cpp b/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.cpp new file mode 100644 index 0000000000..a47f3dd174 --- /dev/null +++ b/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.cpp @@ -0,0 +1,156 @@ +/** \example jkqtplotter_simpletest_advancedlineandfillstyling.cpp + * Shows how to use advanced line styling and filling options with JKQTPlotter + * + * \ref JKQTPlotterAdvancedLineAndFillStyling, JKQTPXYLineGraph, JKQTPSpecialLineHorizontalGraph, JKQTPBarVerticalGraph + */ + +#include +#include "jkqtplotter/jkqtplotter.h" +#include "jkqtplotter/jkqtpgraphsscatter.h" +#include "jkqtplotter/jkqtpgraphsspecialline.h" +#include "jkqtplotter/jkqtpgraphsbarchart.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; + JKQTPDatastore* ds=plot.getDatastore(); + + // 2. now we create data a vector of x-values for a simple plot (a sine curve) + QVector X, Yline, Yfilled, Yfilled2, Ybarsempty, Ybarsfilled; + const int Ndata=20; // number of plot points in each curve + for (int i=0; iaddCopiedColumn(X, "x"); + size_t columnYFilled=ds->addCopiedColumn(Yfilled, "Yfilled"); + size_t columnYFilled2=ds->addCopiedColumn(Yfilled2, "Yfilled2"); + size_t columnYBarsEmpty=ds->addCopiedColumn(Ybarsempty, "Ybarsempty"); + size_t columnYBarsFilled=ds->addCopiedColumn(Ybarsfilled, "Ybarsfilled"); + + + // 3. now we add three semi-transparent, filled curve plots, one for each histogram + JKQTPSpecialLineHorizontalGraph* graphF=new JKQTPSpecialLineHorizontalGraph(&plot); + JKQTPSpecialLineHorizontalGraph* graphF2=new JKQTPSpecialLineHorizontalGraph(&plot); + JKQTPGeoLine* graphL1=new JKQTPGeoLine(&plot, 0, 3, 12, 3.5, Qt::red); + JKQTPGeoLine* graphL2=new JKQTPGeoLine(&plot, 0, 3.8, 12, 4.5, Qt::red); + JKQTPGeoLine* graphL3=new JKQTPGeoLine(&plot, 0, 4.6, 12, 5.5, Qt::red); + JKQTPBarVerticalGraph* graphBE=new JKQTPBarVerticalGraph(&plot); + JKQTPBarVerticalGraph* graphBF=new JKQTPBarVerticalGraph(&plot); + + + // 4. set data + graphF->setXColumn(columnX); graphF->setYColumn(columnYFilled); + graphF2->setXColumn(columnX); graphF2->setYColumn(columnYFilled2); + graphBE->setXColumn(columnX); graphBE->setYColumn(columnYBarsEmpty); + graphBF->setXColumn(columnX); graphBF->setYColumn(columnYBarsFilled); + + // 5. style the graphs + // 5.1 set graph titles + graphL1->setTitle("line 1 graph"); + graphL2->setTitle("line 2 graph"); + graphL3->setTitle("line 3 graph"); + graphF->setTitle("filled curve"); + graphBF->setTitle("bar charts"); + + + // 5.2 set advanced line style (see also https://doc.qt.io/qt-5/qpen.html#setDashPattern) + // and use a gradient-brush to fill the last (thicker) line + QVector dashes1; + dashes1 << 2 << 2 << 2 << 2 << 4 << 4 << 4 << 4 << 8 << 8 << 8 << 8 ; + graphL1->setLineDashPattern(dashes1); + graphL1->setLineWidth(2); + QVector dashes2; + dashes2 << 1 << 2 << 2 << 2 << 3 << 2 << 4 << 2 << 5 << 2 << 6 << 2 ; + graphL2->setLineDashPattern(dashes2); + graphL2->setLineWidth(2); + QVector dashes3; + dashes3 << 4 << 4 << 4 << 4 << 12 << 4 ; + graphL3->setLineDashPattern(dashes3); + graphL3->setLineWidth(4); + QLinearGradient lineGrad(QPointF(0, 0), QPointF(1, 0)); + lineGrad.setColorAt(0, Qt::red); + lineGrad.setColorAt(0.5, Qt::blue); + lineGrad.setColorAt(1, Qt::green); + lineGrad.setCoordinateMode(QGradient::ObjectBoundingMode); + graphL3->setLineBrush(lineGrad); + + + // 5.2 set fill style, using an image, also rotate the images + graphF->setSpecialLineType(JKQTPDirectLine); + graphF->setDrawLine(true); + graphF->setFillTexture(QPixmap(":/example.bmp")); + graphF->setFillTransform(QMatrix(0.5,0,0,0.5,0,0).rotate(45)); + graphF->setFillCurve(true); + graphF->setLineWidth(0.5); + + // 5.3 set fill style, using a custom linear gradient, also with changing transparency (alpha) values + graphF2->setSpecialLineType(JKQTPStepCenter); + graphF2->setDrawLine(false); + graphF2->setFillCurve(true); + QLinearGradient linearGrad(QPointF(0, 0), QPointF(1, 1)); + QColor c1(Qt::yellow); + c1.setAlphaF(0.5); + QColor c2(Qt::red); + QColor c3(Qt::blue); + QColor c4(Qt::green); + c4.setAlphaF(0.5); + linearGrad.setColorAt(0, c1); + linearGrad.setColorAt(0.3, c2); + linearGrad.setColorAt(0.7, c3); + linearGrad.setColorAt(1, c4); + linearGrad.setCoordinateMode(QGradient::ObjectMode); + // use this CoordinateMode, so the gradient fills the whole graph area + graphF2->setFillGradient(linearGrad); + + // 5.4 fill barcharts with transparencies and make the surrounding line invisible (colored transparent) + QColor c0=QColor("darkgreen").darker(); + c0.setAlphaF(.75); + graphBE->setFillColor(c0); + graphBE->setLineColor(Qt::transparent); + QLinearGradient linearG(QPointF(0, 0), QPointF(0, 1)); + QColor cl11(QColor("darkgreen")); + QColor cl12(Qt::green); + cl12.setAlphaF(0.5); + linearG.setColorAt(0, cl11); + linearG.setColorAt(1, cl12); + linearG.setCoordinateMode(QGradient::ObjectMode); + graphBF->setFillGradient(linearG); + graphBF->setLineColor(Qt::transparent); + + + // 6. add the graphs to the plot, so they are actually displayed + plot.addGraph(graphF); + plot.addGraph(graphF2); + plot.addGraph(graphL1); + plot.addGraph(graphL2); + plot.addGraph(graphL3); + plot.addGraph(graphBE); + plot.addGraph(graphBF); + + // 7. set axis labels + plot.getXAxis()->setAxisLabel("x axis"); + plot.getYAxis()->setAxisLabel("y axis"); + plot.setGrid(true); + plot.getPlotter()->setShowKey(false); + + + // 8. scale plot automatically + plot.setXY(0,11.9,-2.5,5.5); + + // 9. show plotter and make it a decent size + plot.show(); + plot.resize(600,600); + + return app.exec(); +} diff --git a/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.pro b/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.pro new file mode 100644 index 0000000000..257033a002 --- /dev/null +++ b/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.pro @@ -0,0 +1,28 @@ +# source code for this simple demo +SOURCES = jkqtplotter_simpletest_advancedlineandfillstyling.cpp + +RESOURCES += jkqtplotter_simpletest_advancedlineandfillstyling.qrc + +# configure Qt +CONFIG += link_prl qt +QT += core gui xml svg +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport + +# output executable name +TARGET = jkqtplotter_simpletest_advancedlineandfillstyling + + +# include JKQTPlotter source code +DEPENDPATH += ../../lib ../../staticlib/jkqtplotterlib +INCLUDEPATH += ../../lib +CONFIG (debug, debug|release) { + LIBS += -L../../staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug +} else { + LIBS += -L../../staticlib/jkqtplotterlib/release -ljkqtplotterlib +} +message("LIBS = $$LIBS") + + + + + diff --git a/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.qrc b/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.qrc new file mode 100644 index 0000000000..77429e32a2 --- /dev/null +++ b/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling.qrc @@ -0,0 +1,5 @@ + + + example.bmp + + diff --git a/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling_and_lib.pro b/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling_and_lib.pro new file mode 100644 index 0000000000..48737bd8af --- /dev/null +++ b/examples/simpletest_advancedlineandfillstyling/jkqtplotter_simpletest_advancedlineandfillstyling_and_lib.pro @@ -0,0 +1,8 @@ +TEMPLATE = subdirs + +SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_advancedlineandfillstyling + +jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro + +jkqtplotter_simpletest_advancedlineandfillstyling.file=$$PWD/jkqtplotter_simpletest_advancedlineandfillstyling.pro +jkqtplotter_simpletest_advancedlineandfillstyling.depends = jkqtplotterlib diff --git a/examples/simpletest_symbols_and_styles/README.md b/examples/simpletest_symbols_and_styles/README.md index dbd8c48e6e..1cc7364da7 100644 --- a/examples/simpletest_symbols_and_styles/README.md +++ b/examples/simpletest_symbols_and_styles/README.md @@ -40,7 +40,9 @@ The source code of the main application can be found in [`jkqtplotter_simpletes } ``` -In addition to the symbol type and line style, you can also alter the size of the symbols (`graph->setSymbolSize(14)`), the line-width used to draw them (`graph->setSymbolLineWidth(1.5)`) and the line width of the graph line (`graph->setLineWidth(1)`). If you want to switch off the line altogether, use `graph->setDrawLine(false`. +In addition to the symbol type and line style, you can also alter the size of the symbols (`graph->setSymbolSize(14)`), the line-width used to draw them (`graph->setSymbolLineWidth(1.5)`) and the line width of the graph line (`graph->setLineWidth(1)`). If you want to switch off the line altogether, use `graph->setDrawLine(false)`. + +Note: There are additional, more advanced options for styling the graphs. See the example [Advanced Line and Fill Styling](@ref JKQTPlotterAdvancedLineAndFillStyling) for details. The result looks like this: diff --git a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp index e434f99211..ab4c46fec4 100644 --- a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp +++ b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp @@ -122,6 +122,16 @@ Qt::PenCapStyle JKQTPGraphLineStyleMixin::getLineCapStyle() const return m_linePen.capStyle(); } +void JKQTPGraphLineStyleMixin::setLineBrush(const QBrush &style) +{ + m_linePen.setBrush(style); +} + +QBrush JKQTPGraphLineStyleMixin::getLineBrush() const +{ + return m_linePen.brush(); +} + QPen JKQTPGraphLineStyleMixin::getLinePen(JKQTPEnhancedPainter& painter, JKQTBasePlotter* parent) const { QPen p=m_linePen; diff --git a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h index 87f7f64044..3da2d3ef21 100644 --- a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h +++ b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h @@ -102,6 +102,14 @@ class JKQTP_LIB_EXPORT JKQTPGraphLineStyleMixin { * \see https://doc.qt.io/qt-5/qpen.html#setCapStyle */ Qt::PenCapStyle getLineCapStyle() const; + /** \brief sets the brush used to fill the line area + * \see https://doc.qt.io/qt-5/qpen.html#setBrush + */ + void setLineBrush(const QBrush& style); + /** \brief gets the brush used to fill the line area + * \see https://doc.qt.io/qt-5/qpen.html#setBrush + */ + QBrush getLineBrush() const; /** \brief set the color of the graph line when highlighted */ diff --git a/screenshots/jkqtplotter_simpletest_advancedlineandfillstyling.png b/screenshots/jkqtplotter_simpletest_advancedlineandfillstyling.png new file mode 100644 index 0000000000..676caa4047 Binary files /dev/null and b/screenshots/jkqtplotter_simpletest_advancedlineandfillstyling.png differ diff --git a/screenshots/jkqtplotter_simpletest_advancedlineandfillstyling_small.png b/screenshots/jkqtplotter_simpletest_advancedlineandfillstyling_small.png new file mode 100644 index 0000000000..b9c8885e0e Binary files /dev/null and b/screenshots/jkqtplotter_simpletest_advancedlineandfillstyling_small.png differ