diff --git a/doc/dox/jkqtplotter.dox b/doc/dox/jkqtplotter.dox index 620e71dc64..60dc74ee15 100644 --- a/doc/dox/jkqtplotter.dox +++ b/doc/dox/jkqtplotter.dox @@ -428,6 +428,9 @@ This group assembles graphs that show their data with symbols and optionally wit \image html geo_line_small.png JKQTPGeoLine, JKQTPGeoInfiniteLine, JKQTPGeoPolyLines + + \image html geo_arrow_small.png + JKQTPGeoArrow \image html geo_rect_small.png JKQTPGeoRectangle diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox index 338ccb9a97..6aa931387a 100644 --- a/doc/dox/whatsnew.dox +++ b/doc/dox/whatsnew.dox @@ -21,6 +21,7 @@ Changes, compared to \ref page_whatsnew_V2019_11 "v2019.11" include:
  • fixed issue #37: CMake installs things into $PREFIX/doc/*.txt , thanks to user:certik
  • fixed issue #45: Build error on mac jkqtfastplotter.cpp:342:28: Variable has incomplete type 'QPainterPath', thanks to user:abdedixit
  • removed the usage of some deprecated functions and objects (e.g. QMatrix)
  • +
  • new: added geometric plot object JKQTPGeoArrow to draw (double-ended) arrows
  • \subsection page_whatsnew_TRUNK_DOWNLOAD trunk: Download diff --git a/doc/images/JKQTPArrow.png b/doc/images/JKQTPArrow.png new file mode 100644 index 0000000000..f94a4e24f8 Binary files /dev/null and b/doc/images/JKQTPArrow.png differ diff --git a/doc/images/JKQTPArrowAndStop.png b/doc/images/JKQTPArrowAndStop.png new file mode 100644 index 0000000000..0b1e3555db Binary files /dev/null and b/doc/images/JKQTPArrowAndStop.png differ diff --git a/doc/images/JKQTPBracketDecorator.png b/doc/images/JKQTPBracketDecorator.png new file mode 100644 index 0000000000..831afd550b Binary files /dev/null and b/doc/images/JKQTPBracketDecorator.png differ diff --git a/doc/images/JKQTPCircleDecorator.png b/doc/images/JKQTPCircleDecorator.png new file mode 100644 index 0000000000..af91d02628 Binary files /dev/null and b/doc/images/JKQTPCircleDecorator.png differ diff --git a/doc/images/JKQTPDoubleArrow.png b/doc/images/JKQTPDoubleArrow.png new file mode 100644 index 0000000000..7c47f888d9 Binary files /dev/null and b/doc/images/JKQTPDoubleArrow.png differ diff --git a/doc/images/JKQTPDoubleArrowAndStop.png b/doc/images/JKQTPDoubleArrowAndStop.png new file mode 100644 index 0000000000..084c16d6c3 Binary files /dev/null and b/doc/images/JKQTPDoubleArrowAndStop.png differ diff --git a/doc/images/JKQTPFilledArrow.png b/doc/images/JKQTPFilledArrow.png new file mode 100644 index 0000000000..5bfa6ce4a6 Binary files /dev/null and b/doc/images/JKQTPFilledArrow.png differ diff --git a/doc/images/JKQTPFilledCircleDecorator.png b/doc/images/JKQTPFilledCircleDecorator.png new file mode 100644 index 0000000000..6a576ab307 Binary files /dev/null and b/doc/images/JKQTPFilledCircleDecorator.png differ diff --git a/doc/images/JKQTPFilledDoubleArrow.png b/doc/images/JKQTPFilledDoubleArrow.png new file mode 100644 index 0000000000..d4967b6693 Binary files /dev/null and b/doc/images/JKQTPFilledDoubleArrow.png differ diff --git a/doc/images/JKQTPFilledRectangleDecorator.png b/doc/images/JKQTPFilledRectangleDecorator.png new file mode 100644 index 0000000000..d26a33ae8c Binary files /dev/null and b/doc/images/JKQTPFilledRectangleDecorator.png differ diff --git a/doc/images/JKQTPFilledTriangleDecorator.png b/doc/images/JKQTPFilledTriangleDecorator.png new file mode 100644 index 0000000000..bf4a75a429 Binary files /dev/null and b/doc/images/JKQTPFilledTriangleDecorator.png differ diff --git a/doc/images/JKQTPFilledTriangleDecoratorAndStop.png b/doc/images/JKQTPFilledTriangleDecoratorAndStop.png new file mode 100644 index 0000000000..07091a1598 Binary files /dev/null and b/doc/images/JKQTPFilledTriangleDecoratorAndStop.png differ diff --git a/doc/images/JKQTPRectangleDecorator.png b/doc/images/JKQTPRectangleDecorator.png new file mode 100644 index 0000000000..af32738b93 Binary files /dev/null and b/doc/images/JKQTPRectangleDecorator.png differ diff --git a/doc/images/JKQTPTriangleDecorator.png b/doc/images/JKQTPTriangleDecorator.png new file mode 100644 index 0000000000..e53ae711e4 Binary files /dev/null and b/doc/images/JKQTPTriangleDecorator.png differ diff --git a/doc/images/JKQTPTriangleDecoratorAndStop.png b/doc/images/JKQTPTriangleDecoratorAndStop.png new file mode 100644 index 0000000000..5f7d140ae5 Binary files /dev/null and b/doc/images/JKQTPTriangleDecoratorAndStop.png differ diff --git a/doc/images/JKQTPVerticalDecorator.png b/doc/images/JKQTPVerticalDecorator.png new file mode 100644 index 0000000000..265ecb3d52 Binary files /dev/null and b/doc/images/JKQTPVerticalDecorator.png differ diff --git a/doc/images/geo_arrow_small.png b/doc/images/geo_arrow_small.png new file mode 100644 index 0000000000..7bb9802541 Binary files /dev/null and b/doc/images/geo_arrow_small.png differ diff --git a/doc/images/plot_geoarrows.png b/doc/images/plot_geoarrows.png new file mode 100644 index 0000000000..554c7b68d9 Binary files /dev/null and b/doc/images/plot_geoarrows.png differ diff --git a/examples/geometric/README.md b/examples/geometric/README.md index bcf852dd34..a98b37ac2b 100644 --- a/examples/geometric/README.md +++ b/examples/geometric/README.md @@ -5,44 +5,47 @@ This project shows the capabilities of JKQTPlotter to also draw geometric elemen The source code of the main application can be found in [`geometric.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/geometric/geometric.cpp). First a plot is generated and the axis aspect ratio is set to 1, so an accurate plot is generated. Then several geometric graphs are added to the plot. Here are some examples, you can find more more examples in the source code of the example: ```.cpp - // a text element + // a text element plot.addGraph(new JKQTPGeoText(&plot, 0.1,0.6, "$x_{1/2}=\\frac{\\sqrt{b^2-4ac}}{2a}$", 10, QColor("red"))); - - // a single symbol + + // a single symbol plot.addGraph(new JKQTPGeoSymbol(&plot, 0.1,0.6, JKQTPCircle, 5, QColor("grey"))); - - // a line + + // a line plot.addGraph(new JKQTPGeoLine(&plot, 1, 0.05, 1.9, 0.9, QColor("red"), 2)); + + // an arrow + plot.addGraph(new JKQTPGeoArrow(&plot, 0.4, 2.5, 0.4, 2.65, QColor("green"), JKQTPArrowAndStop, JKQTPFilledArrow, 1)); - - // a one-sided infinite line with slope dy/dx=0.25/0.2 + + // a one-sided infinite line with slope dy/dx=0.25/0.2 JKQTPGeoInfiniteLine* infLine=new JKQTPGeoInfiniteLine(&plot, 1.7, 0.2, 0.2, 0.25, QColor("green"), 1.5, Qt::PenStyle::DashLine); infLine->setTwoSided(false); infLine->setAlpha(0.5); plot.addGraph(infLine); - - // a polyline + + // a polyline QVector p; p<appendPoint(2.1, 0.5); polygraph->appendPoint(2.9, 0.9); @@ -52,15 +55,15 @@ The source code of the main application can be found in [`geometric.cpp`](https polygraph->setAlpha(0.75); plot.addGraph(polygraph); - + // an arc from an ellipse from -10 degrees to 117 degrees, centered at 2.5,1.5 and full axes of 0.5 and 0.5 plot.addGraph(new JKQTPGeoArc(&plot,2.5,1.5,0.5,0.5, -10, 117 , QColor("orange"), 4, Qt::PenStyle::DashLine)); - + // a pie centered at 2.5,2.5 with ellipse axes 0.9 and 0.9 and from angle 0 degrees to 90 degrees plot.addGraph(new JKQTPGeoPie(&plot,2.5,2.5,0.9,0.9, 0, 90 , QColor("blue"), 4, Qt::PenStyle::SolidLine,QColor("lightblue"))); - + // a chord centered at 2.5,2.5 with ellipse axes 0.9 and 0.9 and from angle 0 degrees to 90 degrees plot.addGraph(new JKQTPGeoChord(&plot,2.5,2.5,0.9,0.9, 0, 90 , QColor("blue"), 4, Qt::PenStyle::SolidLine,QColor("lightblue"))); diff --git a/examples/geometric/geometric.cpp b/examples/geometric/geometric.cpp index 5734ac725a..6322875e55 100644 --- a/examples/geometric/geometric.cpp +++ b/examples/geometric/geometric.cpp @@ -56,8 +56,86 @@ int main(int argc, char* argv[]) infLine->setAlpha(0.5); plot.addGraph(infLine); + // 3.3 some arrows + plot.addGraph(new JKQTPGeoText(&plot, 0.1,2.95, "\\textbf{Arrows:}", 14, QColor("red"))); - // 3.3 some rectangles (you give the center and width/height of the rectangle in the contructor) + JKQTPGeoArrow* a; + double arr_y=2.9; + double arr_deltay=0.9/static_cast(JKQTPLineDecoratorCount); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPArrow, JKQTPNoDecorator, 2)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPArrow", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPFilledArrow, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPFilledArrow", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPTriangleDecorator, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPTriangleArrow", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPFilledTriangleDecorator, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPTriangleFilledArrow", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPTriangleDecoratorAndStop, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPTriangleArrowAndStop", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPFilledTriangleDecoratorAndStop, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPTriangleFilledArrowAndStop", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPDoubleArrow, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPDoubleArrow", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPFilledDoubleArrow, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPFilledDoubleArrow", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPCircleDecorator, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPCircleDecorator", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPFilledCircleDecorator, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPFilledCircleDecorator", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPRectangleDecorator, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPRectangleDecorator", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPFilledRectangleDecorator, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPFilledRectangleDecorator", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPArrowAndStop, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPArrowAndStop", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPDoubleArrowAndStop, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPDoubleArrowAndStop", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPVerticalDecorator, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPVerticalDecorator", 6, a->getLineColor())); + arr_y-=arr_deltay; + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.9, arr_y, QColor("red"), JKQTPBracketDecorator, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.02, a->getY2(), "JKQTPBracketDecorator", 6, a->getLineColor())); + arr_y-=arr_deltay; + + plot.addGraph(new JKQTPGeoArrow(&plot, 0.1, 2.05, 0.9, 2.05, QColor("blue"), JKQTPNoDecorator, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.1, 2.9, 0.75, 2.9, QColor("blue"), JKQTPNoDecorator, JKQTPNoDecorator, 1)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.3, 2.1, 0.1, 2.45, QColor("green"), JKQTPTriangleDecoratorAndStop, JKQTPTriangleDecoratorAndStop, 1)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.2, 2.1, 0.2, 2.45, QColor("blue"), JKQTPNoDecorator, JKQTPFilledTriangleDecoratorAndStop, 3)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.1, 2.1, 0.3, 2.45, QColor("orange"), JKQTPFilledTriangleDecoratorAndStop, JKQTPNoDecorator, 5)); + + plot.addGraph(new JKQTPGeoArrow(&plot, 0.6, 2.1, 0.4, 2.45, QColor("green"), JKQTPTriangleDecorator, JKQTPTriangleDecorator, 0.5)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.5, 2.1, 0.5, 2.45, QColor("blue"), JKQTPNoDecorator, JKQTPArrowAndStop, 2)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.4, 2.1, 0.6, 2.45, QColor("orange"), JKQTPArrowAndStop, JKQTPNoDecorator, 4)); + + plot.addGraph(new JKQTPGeoArrow(&plot, 0.4, 2.5, 0.4, 2.65, QColor("green"), JKQTPArrowAndStop, JKQTPFilledArrow, 0.5)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.45, 2.5, 0.45, 2.65, QColor("blue"), JKQTPArrowAndStop, JKQTPFilledArrow, 1)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.5, 2.5, 0.5, 2.65, QColor("orange"), JKQTPArrowAndStop, JKQTPFilledArrow, 1.5)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.55, 2.5, 0.55, 2.65, QColor("blue"), JKQTPArrowAndStop, JKQTPFilledArrow, 2)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.6, 2.5, 0.6, 2.65, QColor("orange"), JKQTPArrowAndStop, JKQTPFilledArrow, 2.5)); + + plot.addGraph(new JKQTPGeoArrow(&plot, 0.4, 2.7, 0.4, 2.9, QColor("green"), JKQTPTriangleDecoratorAndStop, JKQTPFilledCircleDecorator, 0.5)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.45, 2.7, 0.45, 2.9, QColor("blue"), JKQTPTriangleDecoratorAndStop, JKQTPFilledCircleDecorator, 1)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.5, 2.7, 0.5, 2.9, QColor("orange"), JKQTPTriangleDecoratorAndStop, JKQTPFilledCircleDecorator, 1.5)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.55, 2.7, 0.55, 2.9, QColor("blue"), JKQTPTriangleDecoratorAndStop, JKQTPFilledCircleDecorator, 2)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.6, 2.7, 0.6, 2.9, QColor("orange"), JKQTPTriangleDecoratorAndStop, JKQTPFilledCircleDecorator, 2.5)); + + + + // 3.4 some rectangles (you give the center and width/height of the rectangle in the contructor) plot.addGraph(new JKQTPGeoText(&plot, 0.1,1.95, "\\textbf{Rectangles:}", 14, QColor("red"))); plot.addGraph(new JKQTPGeoRectangle(&plot, 0.5,1.5,0.8,0.8, QColor("blue"), 1, Qt::SolidLine, QColor("lightblue"))); QColor rfill("lightblue"); rfill.setAlphaF(0.5); @@ -69,7 +147,7 @@ int main(int argc, char* argv[]) plot.addGraph(new JKQTPGeoSymbol(&plot, 0.9,1.6, JKQTPCircle, 5, QColor("grey"))); - // 3.4 some circles and elllipses + // 3.5 some circles and elllipses plot.addGraph(new JKQTPGeoText(&plot, 1.1,1.95, "\\textbf{Circles/Ellipses:}", 14, QColor("red"))); QColor col=QColor("blue"); col.setAlphaF(0.2); plot.addGraph(new JKQTPGeoRectangle(&plot, 1.5,1.5,0.8,0.8, col, 0.5, Qt::SolidLine)); @@ -92,7 +170,7 @@ int main(int argc, char* argv[]) plot.addGraph(new JKQTPGeoSymbol(&plot, 1.9,1.6, JKQTPCircle, 5, QColor("grey"))); - // 3.5 some polygon elements + // 3.6 some polygon elements plot.addGraph(new JKQTPGeoText(&plot, 2.1,0.95, "\\textbf{PolyLines/Polygons:}", 14, QColor("red"))); QVector polygon; polygon<"||s=="<-"||s==">"||s=="<") return JKQTPArrow; + if (s=="filled_arrow") return JKQTPFilledArrow; + if (s=="triangle") return JKQTPTriangleDecorator; + if (s=="filled_triangle") return JKQTPFilledTriangleDecorator; + if (s=="triangle_stop") return JKQTPTriangleDecoratorAndStop; + if (s=="filled_triangle_stop") return JKQTPFilledTriangleDecoratorAndStop; + if (s=="double_arrow") return JKQTPDoubleArrow; + if (s=="filled_double_arrow") return JKQTPFilledDoubleArrow; + if (s=="circle") return JKQTPCircleDecorator; + if (s=="filled_circle") return JKQTPFilledCircleDecorator; + if (s=="rectangle") return JKQTPRectangleDecorator; + if (s=="filled_rectangle") return JKQTPFilledRectangleDecorator; + if (s=="arrow_stop") return JKQTPArrowAndStop; + if (s=="double_arrow_stop") return JKQTPDoubleArrowAndStop; + if (s=="vertical_line") return JKQTPVerticalDecorator; + if (s=="bracket") return JKQTPBracketDecorator; + + return JKQTPNoDecorator; +} diff --git a/lib/jkqtcommon/jkqtpdrawingtools.h b/lib/jkqtcommon/jkqtpdrawingtools.h index 0c311c108d..01b0f16d5a 100644 --- a/lib/jkqtcommon/jkqtpdrawingtools.h +++ b/lib/jkqtcommon/jkqtpdrawingtools.h @@ -34,6 +34,7 @@ #include #include #include +#include #include "jkqtcommon/jkqtpmathtools.h" #include "jkqtcommon/jkqtpcodestructuring.h" @@ -151,6 +152,65 @@ JKQTCOMMON_LIB_EXPORT JKQTPGraphSymbols String2JKQTPGraphSymbols(const QString& + +/** \brief symbols that can be used to plot a datapoint for a graph + * \ingroup jkqtptools_drawing + */ +enum JKQTPLineDecoratorStyle { + JKQTPNoDecorator=0, /*!< \brief no decorator, i.e. a simple line-end */ + JKQTPArrow, /*!< \brief a simple arrow tip, unfilled \image html JKQTPArrow.png*/ + JKQTPFilledArrow, /*!< \brief a nice filled arrow tip \image html JKQTPFilledArrow.png */ + JKQTPTriangleDecorator, /*!< \brief a triangular arrow tip \image html JKQTPTriangleDecorator.png */ + JKQTPFilledTriangleDecorator, /*!< \brief a triangular filled arrow tip \image html JKQTPFilledTriangleDecorator.png */ + JKQTPTriangleDecoratorAndStop, /*!< \brief a triangular arrow tip with a stop-line \image html JKQTPTriangleDecoratorAndStop.png */ + JKQTPFilledTriangleDecoratorAndStop, /*!< \brief a triangular filled arrow tip with a stop-line \image html JKQTPFilledTriangleDecoratorAndStop.png */ + JKQTPDoubleArrow, /*!< \brief a nice double-arrow tip \image html JKQTPDoubleArrow.png*/ + JKQTPFilledDoubleArrow, /*!< \brief a nice filled double-arrow tip \image html JKQTPFilledDoubleArrow.png */ + JKQTPCircleDecorator, /*!< \brief an open circle tip \image html JKQTPCircleDecorator.png */ + JKQTPFilledCircleDecorator, /*!< \brief a filled circle tip \image html JKQTPFilledCircleDecorator.png */ + JKQTPRectangleDecorator, /*!< \brief an open rectangle tip \image html JKQTPRectangleDecorator.png */ + JKQTPFilledRectangleDecorator, /*!< \brief a filled rectangle tip \image html JKQTPFilledRectangleDecorator.png */ + JKQTPArrowAndStop, /*!< \brief a simple arrow tip, unfilled with stop-line \image html JKQTPArrowAndStop.png */ + JKQTPDoubleArrowAndStop, /*!< \brief a simple double-arrow tip, unfilled with stop-line \image html JKQTPDoubleArrowAndStop.png */ + JKQTPVerticalDecorator, /*!< \brief a simple vertical stop-line \image html JKQTPVerticalDecorator.png */ + JKQTPBracketDecorator, /*!< \brief a vertical bracket decorator \image html JKQTPBracketDecorator.png */ + + JKQTPLineDecoratorCount, /*!< \brief can be used to iterate over all symbols using: for (int i=0; i(JKQTPSymbolCount); i++) { JKQTPLineDecoratorStyle s=static_cast(i); ... } */ + JKQTPMaxLineDecoratorID=JKQTPLineDecoratorCount-1, /*!< \brief points to the last available symbol, can be used to iterate over all symbols: for (int i=0; i<=static_cast(JKQTPMaxSymbolID); i++) { JKQTPLineDecoratorStyle s=static_cast(i); ... } */ + JKQTPDefaultLineDecorator=JKQTPFilledArrow /*!< \brief a default symbol used for plotting */ +}; + +/** \brief converts a JKQTPLineDecoratorStyle variable into a identifier string + * \ingroup jkqtptools_drawing + */ +JKQTCOMMON_LIB_EXPORT QString JKQTPLineDecoratorStyle2String(JKQTPLineDecoratorStyle pos); +/** \brief converts a JKQTPLineDecoratorStyle variable into a human-readable string + * \ingroup jkqtptools_drawing + */ +JKQTCOMMON_LIB_EXPORT QString JKQTPLineDecoratorStyle2NameString(JKQTPLineDecoratorStyle pos); + +/** \brief converts a String into a JKQTPLineDecoratorStyle + * \ingroup jkqtptools_drawing + */ +JKQTCOMMON_LIB_EXPORT JKQTPLineDecoratorStyle String2JKQTPLineDecoratorStyle(const QString& pos); + +/*! \brief plot the specified symbol at pixel position x,y. Note that this function only draws the decorator, NOT the line pointing to it! + \ingroup jkqtptools_drawing + + \tparam TPainter Type of \a painter: A class like JKQTPEnhancedPainter or QPainter + \param painter the QPainter to draw to + \param x x-coordinate of the decorator tip + \param y y-coordinate of the decorator tip + \param angle_rad angle of the line pointing to (x,y), given in radians, 0rad points to the right, >0rad is a counter-clockwise rotation, as calculated by atan2() from dx, dy of a line! + \param style type of the decorator to plot, see JKQTPLineDecoratorStyle + \param size size of the decorator + \param[out] line_start optional output parameter: when drawing the line let it end here, not necessarily at (x,y) + */ +template +inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double angle_rad, JKQTPLineDecoratorStyle style, double size, QPointF* line_start=nullptr); + + + /** \brief rotate a rectangle by given angle (rotates all points around the center of the rectangle and returns it as a QPolygonF) * \ingroup jkqtptools_drawing */ @@ -855,4 +915,143 @@ inline void JKQTPDrawTooltip(TPainter& painter, double x, double y, const QRectF painter.drawRect(rect); } } + +template +inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double angle_rad, JKQTPLineDecoratorStyle style, double size, QPointF* line_start) { + if (line_start) *line_start=QPointF(x,y); + static double default_theta_open_tip=60.0/2.0 /180.0*JKQTPSTATISTICS_PI; + static double tan__default_theta_open_tip=tan(default_theta_open_tip); + static double default_theta_closed_tip=50.0/2.0 /180.0*JKQTPSTATISTICS_PI; + static double tan__default_theta_closed_tip=tan(default_theta_closed_tip); + const QPen pinit=painter.pen(); + QPen p0=pinit; + p0.setWidthF(0); + { + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.translate(x,y); + painter.rotate(angle_rad/JKQTPSTATISTICS_PI*180.0); + painter.setPen(p0); + + switch(style) { + case JKQTPArrow: + case JKQTPArrowAndStop: { + const QPointF poly[3] = { + QPointF(size, -tan__default_theta_open_tip*size), + QPointF(0,0), + QPointF(size, tan__default_theta_open_tip*size) + }; + painter.setPen(pinit); + if (style==JKQTPArrowAndStop) painter.drawLine(QPointF(0,-tan__default_theta_open_tip*size), QPointF(0,tan__default_theta_open_tip*size)); + painter.drawPolyline(poly, 3); + } break; + case JKQTPDoubleArrow: + case JKQTPDoubleArrowAndStop: { + const QPointF poly[3] = { + QPointF(size, -tan__default_theta_open_tip*size), + QPointF(0,0), + QPointF(size, tan__default_theta_open_tip*size) + }; + painter.setPen(pinit); + if (style==JKQTPDoubleArrowAndStop) painter.drawLine(QPointF(0,-tan__default_theta_open_tip*size), QPointF(0,tan__default_theta_open_tip*size)); + painter.drawPolyline(poly, 3); + painter.translate(4.0*pinit.widthF(),0); + painter.drawPolyline(poly, 3); + if (line_start) *line_start=QPointF(x,y)+QPointF(4.0*pinit.widthF()*cos(angle_rad),4.0*pinit.widthF()*sin(angle_rad)); + } break; + case JKQTPFilledArrow: + case JKQTPFilledDoubleArrow: { + const QPointF poly[4] = { + QPointF(0,0), + QPointF(size, tan__default_theta_closed_tip*size), + QPointF(0.75*size,0), + QPointF(size, -tan__default_theta_closed_tip*size) + }; + painter.drawPolygon(poly, 4); + if (style==JKQTPFilledDoubleArrow) { + painter.translate(0.25*size, 0); + painter.drawPolygon(poly, 4); + if (line_start) *line_start=QPointF(x,y)+QPointF(size*cos(angle_rad),size*sin(angle_rad)); + } else { + if (line_start) *line_start=QPointF(x,y)+QPointF(0.75*size*cos(angle_rad),0.75*size*sin(angle_rad)); + } + } break; + + case JKQTPTriangleDecorator: + case JKQTPTriangleDecoratorAndStop: { + const QPointF poly[3] = { + QPointF(size, -tan__default_theta_closed_tip*size), + QPointF(0,0), + QPointF(size, tan__default_theta_closed_tip*size) + }; + painter.setBrush(Qt::NoBrush); + painter.setPen(pinit); + painter.drawConvexPolygon(poly, 3); + if (style==JKQTPTriangleDecoratorAndStop) painter.drawLine(QPointF(0,-tan__default_theta_closed_tip*size), QPointF(0,tan__default_theta_closed_tip*size)); + if (line_start) *line_start=QPointF(x,y)+QPointF(size*cos(angle_rad),size*sin(angle_rad)); + } break; + + case JKQTPFilledTriangleDecorator: + case JKQTPFilledTriangleDecoratorAndStop: { + const QPointF poly[3] = { + QPointF(size, -tan__default_theta_closed_tip*size), + QPointF(0,0), + QPointF(size, tan__default_theta_closed_tip*size) + }; + painter.setPen(p0); + painter.drawConvexPolygon(poly, 3); + if (style==JKQTPFilledTriangleDecoratorAndStop) { + painter.setPen(pinit); + painter.drawLine(QPointF(0,-tan__default_theta_closed_tip*size), QPointF(0,tan__default_theta_closed_tip*size)); + } + if (line_start) *line_start=QPointF(x,y)+QPointF(size*cos(angle_rad),size*sin(angle_rad)); + } break; + + + + + case JKQTPCircleDecorator: + case JKQTPFilledCircleDecorator: { + if (style==JKQTPCircleDecorator) { + painter.setBrush(Qt::NoBrush); + painter.setPen(pinit); + } else { + painter.setPen(p0); + } + painter.drawEllipse(QRectF(-size/2.0,-size/2.0,size,size)); + if (line_start) *line_start=QPointF(x,y)+QPointF(size/2.0*cos(angle_rad),size/2.0*sin(angle_rad)); + } break; + + case JKQTPRectangleDecorator: + case JKQTPFilledRectangleDecorator: { + if (style==JKQTPRectangleDecorator) { + painter.setBrush(Qt::NoBrush); + painter.setPen(pinit); + } else { + painter.setPen(p0); + } + painter.drawRect(QRectF(-size/2.0,-size/2.0,size,size)); + if (line_start) *line_start=QPointF(x,y)+QPointF(size/2.0*cos(angle_rad),size/2.0*sin(angle_rad)); + } break; + case JKQTPVerticalDecorator: { + painter.setPen(pinit); + painter.drawLine(QPointF(0,-tan__default_theta_open_tip*size), QPointF(0,tan__default_theta_open_tip*size)); + } break; + + case JKQTPBracketDecorator: { + const QPointF poly[4] = { + QPointF(-size*0.2,-tan__default_theta_open_tip*size), + QPointF(0,-tan__default_theta_open_tip*size), + QPointF(0,tan__default_theta_open_tip*size), + QPointF(-size*0.2, tan__default_theta_open_tip*size) + }; + painter.setPen(pinit); + painter.drawPolyline(poly, 4); + } break; + case JKQTPNoDecorator: break; + } + + } +} + + #endif // JKQTPDRAWINGTOOLS_H_INCLUDED diff --git a/lib/jkqtplotter/graphs/jkqtpgeometric.cpp b/lib/jkqtplotter/graphs/jkqtpgeometric.cpp index 972caead83..81ebc98216 100644 --- a/lib/jkqtplotter/graphs/jkqtpgeometric.cpp +++ b/lib/jkqtplotter/graphs/jkqtpgeometric.cpp @@ -359,6 +359,109 @@ double JKQTPGeoLine::getY2() const + + +JKQTPGeoArrow::JKQTPGeoArrow(JKQTBasePlotter* parent, double x1, double y1, double x2, double y2, QColor color, JKQTPLineDecoratorStyle headStyle, JKQTPLineDecoratorStyle tailStyle, double lineWidth, Qt::PenStyle style): + JKQTPGeoBaseDecoratedLine(color, lineWidth, headStyle, tailStyle, style, parent) +{ + this->x1=x1; + this->y1=y1; + this->x2=x2; + this->y2=y2; +} + +JKQTPGeoArrow::JKQTPGeoArrow(JKQTPlotter* parent, double x1, double y1, double x2, double y2, QColor color, JKQTPLineDecoratorStyle headStyle, JKQTPLineDecoratorStyle tailStyle, double lineWidth, Qt::PenStyle style): + JKQTPGeoArrow(parent->getPlotter(), x1,y1,x2,y2,color, headStyle, tailStyle, lineWidth, style) +{ +} + + +bool JKQTPGeoArrow::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) { + minx=qMin(x1, x2); + maxx=qMax(x1, x2); + smallestGreaterZero=0; + double xvsgz; + xvsgz=x1; SmallestGreaterZeroCompare_xvsgz(); + xvsgz=x2; SmallestGreaterZeroCompare_xvsgz(); + return true; +} + +bool JKQTPGeoArrow::getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) { + miny=qMin(y1, y2); + maxy=qMax(y1, y2); + smallestGreaterZero=0; + double xvsgz; + xvsgz=y1; SmallestGreaterZeroCompare_xvsgz(); + xvsgz=y2; SmallestGreaterZeroCompare_xvsgz(); + return true; +} + +void JKQTPGeoArrow::draw(JKQTPEnhancedPainter& painter) { + clearHitTestData(); + reserveHitTestData(2); + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.setPen(getLinePen(painter, parent)); + painter.setBrush(getLineColor()); + QPointF xx1(transformX(x1),transformY(y1)); + QPointF xx2(transformX(x2), transformY(y2)); + const double angle1=atan2(xx2.y()-xx1.y(), xx2.x()-xx1.x()); + const double angle2=atan2(xx1.y()-xx2.y(), xx1.x()-xx2.x()); + if ( QLineF(xx1, xx2).length()>0) { + QPointF lx1=xx1, lx2=xx2; + JKQTPPlotLineDecorator(painter, xx1.x(), xx1.y(), angle1, getTailDecoratorStyle(), getTailDecoratorSizeFactor()*getLinePen(painter, getParent()).widthF(), &lx1); + JKQTPPlotLineDecorator(painter, xx2.x(), xx2.y(), angle2, getHeadDecoratorStyle(), getHeadDecoratorSizeFactor()*getLinePen(painter, getParent()).widthF(), &lx2); + // draw corrected line + painter.drawLine(QLineF(lx1, lx2)); + addHitTestData(x1, y1); + addHitTestData(x2, y2); + } + +} + +void JKQTPGeoArrow::setX1(double __value) +{ + this->x1 = __value; +} + +double JKQTPGeoArrow::getX1() const +{ + return this->x1; +} + +void JKQTPGeoArrow::setY1(double __value) +{ + this->y1 = __value; +} + +double JKQTPGeoArrow::getY1() const +{ + return this->y1; +} + +void JKQTPGeoArrow::setX2(double __value) +{ + this->x2 = __value; +} + +double JKQTPGeoArrow::getX2() const +{ + return this->x2; +} + +void JKQTPGeoArrow::setY2(double __value) +{ + this->y2 = __value; +} + +double JKQTPGeoArrow::getY2() const +{ + return this->y2; +} + + + + + JKQTPGeoInfiniteLine::JKQTPGeoInfiniteLine(JKQTBasePlotter* parent, double x, double y, double dx, double dy, QColor color, double lineWidth, Qt::PenStyle style): JKQTPGeoBaseLine(color, lineWidth, style, parent) { @@ -1374,3 +1477,56 @@ QColor JKQTPGeoSymbol::getKeyLabelColor() const { return getSymbolColor(); } + +JKQTPGeoBaseDecoratedLine::JKQTPGeoBaseDecoratedLine(QColor color, double lineWidth, JKQTPLineDecoratorStyle headStyle, JKQTPLineDecoratorStyle tailStyle, Qt::PenStyle style, JKQTBasePlotter *parent): + JKQTPPlotObject(parent) +{ + setLineColor(color); + setLineWidth(lineWidth); + setLineStyle(style); + setTailDecoratorStyle(tailStyle); + setHeadDecoratorStyle(headStyle); +} + +JKQTPGeoBaseDecoratedLine::JKQTPGeoBaseDecoratedLine(QColor color, double lineWidth, JKQTPLineDecoratorStyle headStyle, JKQTPLineDecoratorStyle tailStyle, Qt::PenStyle style, JKQTPlotter *parent): + JKQTPGeoBaseDecoratedLine(color, lineWidth, headStyle, tailStyle, style, parent->getPlotter()) +{ + +} + +JKQTPGeoBaseDecoratedLine::JKQTPGeoBaseDecoratedLine(JKQTBasePlotter *parent): + JKQTPPlotObject(parent) +{ + +} + +JKQTPGeoBaseDecoratedLine::JKQTPGeoBaseDecoratedLine(JKQTPlotter *parent): + JKQTPPlotObject(parent->getPlotter()) +{ + +} + +void JKQTPGeoBaseDecoratedLine::setAlpha(float alpha) +{ + auto color=getLineColor(); + color.setAlphaF(alpha); + setLineColor(color); +} + +void JKQTPGeoBaseDecoratedLine::setColor(QColor c) +{ + setLineColor(c); +} + +void JKQTPGeoBaseDecoratedLine::drawKeyMarker(JKQTPEnhancedPainter &painter, QRectF &rect) +{ + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.setPen(getLinePen(painter, parent)); + double y=rect.top()+rect.height()/2.0; + if (rect.width()>0) painter.drawLine(QLineF(rect.left(), y, rect.right(), y)); +} + +QColor JKQTPGeoBaseDecoratedLine::getKeyLabelColor() const +{ + return getLineColor(); +} diff --git a/lib/jkqtplotter/graphs/jkqtpgeometric.h b/lib/jkqtplotter/graphs/jkqtpgeometric.h index 131513399a..9d9bb7ece3 100644 --- a/lib/jkqtplotter/graphs/jkqtpgeometric.h +++ b/lib/jkqtplotter/graphs/jkqtpgeometric.h @@ -35,48 +35,100 @@ elements that only consist of lines (i.e. no filling of any kind is done) \ingroup jkqtplotter_geoplots - */ -class JKQTPLOTTER_LIB_EXPORT JKQTPGeoBaseLine: public JKQTPPlotObject, public JKQTPGraphLineStyleMixin { - Q_OBJECT - public: - /*! \brief class contructor +*/ + class JKQTPLOTTER_LIB_EXPORT JKQTPGeoBaseLine: public JKQTPPlotObject, public JKQTPGraphLineStyleMixin { + Q_OBJECT +public: + /*! \brief class contructor - \param color color of drawing - \param style line style of drawing - \param lineWidth lineWidth of drawing - \param parent the parent plotter object - */ - explicit JKQTPGeoBaseLine(QColor color, double lineWidth, Qt::PenStyle style=Qt::SolidLine, JKQTBasePlotter* parent=nullptr); - /*! \brief class contructor + \param color color of drawing + \param style line style of drawing + \param lineWidth lineWidth of drawing + \param parent the parent plotter object + */ + explicit JKQTPGeoBaseLine(QColor color, double lineWidth, Qt::PenStyle style=Qt::SolidLine, JKQTBasePlotter* parent=nullptr); + /*! \brief class contructor - \param color color of drawing - \param style line style of drawing - \param lineWidth lineWidth of drawing - \param parent the parent plotter object - */ - explicit JKQTPGeoBaseLine(QColor color, double lineWidth, Qt::PenStyle style, JKQTPlotter* parent); - /*! \brief class contructor + \param color color of drawing + \param style line style of drawing + \param lineWidth lineWidth of drawing + \param parent the parent plotter object + */ + explicit JKQTPGeoBaseLine(QColor color, double lineWidth, Qt::PenStyle style, JKQTPlotter* parent); + /*! \brief class contructor - */ - explicit JKQTPGeoBaseLine(JKQTBasePlotter* parent); - /*! \brief class contructor + */ + explicit JKQTPGeoBaseLine(JKQTBasePlotter* parent); + /*! \brief class contructor - */ - explicit JKQTPGeoBaseLine(JKQTPlotter* parent); + */ + explicit JKQTPGeoBaseLine(JKQTPlotter* parent); - /** \brief sets the alpha-channel of the \a color (i.e. its transparency) */ - virtual void setAlpha(float alpha); - /** \brief set line color */ - virtual void setColor(QColor c); + /** \brief sets the alpha-channel of the \a color (i.e. its transparency) */ + virtual void setAlpha(float alpha); + /** \brief set line color */ + virtual void setColor(QColor c); - /** \brief plots a key marker inside the specified rectangle \a rect */ - virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) override; - /** \brief returns the color to be used for the key label */ - virtual QColor getKeyLabelColor() const override; + /** \brief plots a key marker inside the specified rectangle \a rect */ + virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) override; + /** \brief returns the color to be used for the key label */ + virtual QColor getKeyLabelColor() const override; - protected: +protected: + +}; +/*! \brief This JKQTPPlotObject is used as base class for geometric drawing + elements that consist of lines with decorated ends (i.e. no filling of any kind is done) + \ingroup jkqtplotter_geoplots + +*/ +class JKQTPLOTTER_LIB_EXPORT JKQTPGeoBaseDecoratedLine: public JKQTPPlotObject, public JKQTPGraphDecoratedLineStyleMixin { + Q_OBJECT +public: + /*! \brief class contructor + + \param color color of drawing + \param lineWidth lineWidth of drawing + \param headStyle style of the head decoration + \param tailStyle style of the tail decoration + \param style line style of drawing + \param parent the parent plotter object + */ + explicit JKQTPGeoBaseDecoratedLine(QColor color, double lineWidth, JKQTPLineDecoratorStyle headStyle, JKQTPLineDecoratorStyle tailStyle, Qt::PenStyle style=Qt::SolidLine, JKQTBasePlotter* parent=nullptr); + /*! \brief class contructor + + \param color color of drawing + \param lineWidth lineWidth of drawing + \param headStyle style of the head decoration + \param tailStyle style of the tail decoration + \param style line style of drawing + \param parent the parent plotter object + */ + explicit JKQTPGeoBaseDecoratedLine(QColor color, double lineWidth, JKQTPLineDecoratorStyle headStyle, JKQTPLineDecoratorStyle tailStyle, Qt::PenStyle style, JKQTPlotter* parent); + /*! \brief class contructor + + */ + explicit JKQTPGeoBaseDecoratedLine(JKQTBasePlotter* parent); + /*! \brief class contructor + + */ + explicit JKQTPGeoBaseDecoratedLine(JKQTPlotter* parent); + + + + /** \brief sets the alpha-channel of the \a color (i.e. its transparency) */ + virtual void setAlpha(float alpha); + /** \brief set line color */ + virtual void setColor(QColor c); + + /** \brief plots a key marker inside the specified rectangle \a rect */ + virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) override; + /** \brief returns the color to be used for the key label */ + virtual QColor getKeyLabelColor() const override; + +protected: }; @@ -153,6 +205,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoBaseFilled: public JKQTPGeoBaseLine, public /*! \brief This virtual JKQTPGraph descendent may be used to display a single symbol (marker). \ingroup jkqtplotter_geoplots + \see \ref JKQTPlotterGeometricGraphs + */ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoSymbol: public JKQTPPlotObject, public JKQTPGraphSymbolStyleMixin { Q_OBJECT @@ -218,6 +272,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoSymbol: public JKQTPPlotObject, public JKQT class in order to display LaTeX formulas. \ingroup jkqtplotter_geoplots + \see \ref JKQTPlotterGeometricGraphs */ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoText: public JKQTPPlotObject, public JKQTPGraphTextStyleMixin { Q_OBJECT @@ -305,6 +360,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoText: public JKQTPPlotObject, public JKQTPG \image html plot_geoline.png + \see \ref JKQTPlotterGeometricGraphs + */ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoLine: public JKQTPGeoBaseLine { Q_OBJECT @@ -394,6 +451,80 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoLine: public JKQTPGeoBaseLine { }; +/*! \brief This JKQTPPlotObject is used to draw a line with decorations (e.g. arrows) + \ingroup jkqtplotter_geoplots + + \image html plot_geoarrows.png + + \see \ref JKQTPlotterGeometricGraphs + + */ +class JKQTPLOTTER_LIB_EXPORT JKQTPGeoArrow: public JKQTPGeoBaseDecoratedLine { + Q_OBJECT +public: + /*! \brief class constructor + + \param parent the parent plotter object + \param x1 x-coordinate of first point of line + \param y1 y-coordinate of first point of line + \param x2 x-coordinate of second point of line + \param y2 y-coordinate of second point of line + \param color color of line + \param lineWidth width of line + \param style line style + \param parent the parent plotter object + */ + JKQTPGeoArrow(JKQTBasePlotter* parent, double x1, double y1, double x2, double y2, QColor color, JKQTPLineDecoratorStyle headStyle=JKQTPDefaultLineDecorator, JKQTPLineDecoratorStyle tailStyle=JKQTPNoDecorator, double lineWidth=1.0, Qt::PenStyle style=Qt::SolidLine); + /*! \brief class constructor + + \param parent the parent plotter object + \param x1 x-coordinate of first point of line + \param y1 y-coordinate of first point of line + \param x2 x-coordinate of second point of line + \param y2 y-coordinate of second point of line + \param color color of line + \param lineWidth width of line + \param style line style + \param parent the parent plotter object + */ + JKQTPGeoArrow(JKQTPlotter* parent, double x1, double y1, double x2, double y2, QColor color, JKQTPLineDecoratorStyle headStyle=JKQTPDefaultLineDecorator, JKQTPLineDecoratorStyle tailStyle=JKQTPNoDecorator, double lineWidth=1.0, Qt::PenStyle style=Qt::SolidLine); + + + /** \copydoc JKQTPPlotObject::getXMinMax() */ + virtual bool getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) override; + /** \copydoc JKQTPPlotObject::getYMinMax() */ + virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override; + + /** \brief plots the graph to the plotter object specified as parent */ + virtual void draw(JKQTPEnhancedPainter& painter) override; + + /*! \copydoc x1 */ + void setX1(double __value); + /*! \copydoc x1 */ + double getX1() const; + /*! \copydoc y1 */ + void setY1(double __value); + /*! \copydoc y1 */ + double getY1() const; + /*! \copydoc x2 */ + void setX2(double __value); + /*! \copydoc x2 */ + double getX2() const; + /*! \copydoc y2 */ + void setY2(double __value); + /*! \copydoc y2 */ + double getY2() const; +protected: + /** \brief x-coordinate of first point of line */ + double x1; + /** \brief y-coordinate of first point of line */ + double y1; + /** \brief x-coordinate of second point of line */ + double x2; + /** \brief y-coordinate of second point of line */ + double y2; + +}; /*! \brief This JKQTPPlotObject is used to draw an infinite line \ingroup jkqtplotter_geoplots @@ -403,6 +534,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoLine: public JKQTPGeoBaseLine { \image html plot_geoinfiniteline.png + \see \ref JKQTPlotterGeometricGraphs + */ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoInfiniteLine: public JKQTPGeoBaseLine { Q_OBJECT @@ -481,6 +614,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoInfiniteLine: public JKQTPGeoBaseLine { \image html plot_geolines.png + \see \ref JKQTPlotterGeometricGraphs + */ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoPolyLines: public JKQTPGeoBaseLine { Q_OBJECT @@ -548,6 +683,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoPolyLines: public JKQTPGeoBaseLine { \ingroup jkqtplotter_geoplots \image html plot_georectangle.png + + \see \ref JKQTPlotterGeometricGraphs */ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoRectangle: public JKQTPGeoBaseFilled { Q_OBJECT @@ -690,6 +827,8 @@ protected: \image html plot_geopolygon.png + \see \ref JKQTPlotterGeometricGraphs + */ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoPolygon: public JKQTPGeoBaseFilled { Q_OBJECT @@ -772,6 +911,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoPolygon: public JKQTPGeoBaseFilled { \see http://www.codeguru.com/cpp/g-m/gdi/article.php/c131 and http://en.wikipedia.org/wiki/Ellipse#General_parametric_form + + \see \ref JKQTPlotterGeometricGraphs */ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoEllipse: public JKQTPGeoRectangle { Q_OBJECT @@ -878,6 +1019,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoEllipse: public JKQTPGeoRectangle { \ingroup jkqtplotter_geoplots \image html plot_geoarc.png + + \see \ref JKQTPlotterGeometricGraphs */ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoArc: public JKQTPGeoBaseLine { Q_OBJECT @@ -987,6 +1130,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoArc: public JKQTPGeoBaseLine { \ingroup jkqtplotter_geoplots \image html plot_geopie.png + + \see \ref JKQTPlotterGeometricGraphs */ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoPie: public JKQTPGeoEllipse { Q_OBJECT @@ -1056,6 +1201,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoPie: public JKQTPGeoEllipse { \ingroup jkqtplotter_geoplots \image html plot_geochord.png + + \see \ref JKQTPlotterGeometricGraphs */ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoChord: public JKQTPGeoPie { Q_OBJECT diff --git a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp index 6e98bf4693..efd944f8dc 100644 --- a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp +++ b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp @@ -450,3 +450,61 @@ QColor JKQTPGraphTextStyleMixin::getTextColor() const { return m_textColor; } + +JKQTPGraphDecoratedLineStyleMixin::JKQTPGraphDecoratedLineStyleMixin(): + JKQTPGraphLineStyleMixin() +{ + m_headDecoratorStyle=JKQTPLineDecoratorStyle::JKQTPDefaultLineDecorator; + m_tailDecoratorStyle=JKQTPLineDecoratorStyle::JKQTPNoDecorator; + m_tailDecoratorSizeFactor=m_headDecoratorSizeFactor=9.0; +} + +void JKQTPGraphDecoratedLineStyleMixin::initDecoratedLineStyle(JKQTBasePlotter *parent, int &parentPlotStyle) +{ + initLineStyle(parent, parentPlotStyle); +} + +JKQTPGraphDecoratedLineStyleMixin::~JKQTPGraphDecoratedLineStyleMixin() +{ + +} + +void JKQTPGraphDecoratedLineStyleMixin::setHeadDecoratorStyle(const JKQTPLineDecoratorStyle &__value) +{ + m_headDecoratorStyle=__value; +} + +JKQTPLineDecoratorStyle JKQTPGraphDecoratedLineStyleMixin::getHeadDecoratorStyle() const +{ + return m_headDecoratorStyle; +} + +void JKQTPGraphDecoratedLineStyleMixin::setTailDecoratorStyle(const JKQTPLineDecoratorStyle &__value) +{ + m_tailDecoratorStyle=__value; +} + +JKQTPLineDecoratorStyle JKQTPGraphDecoratedLineStyleMixin::getTailDecoratorStyle() const +{ + return m_tailDecoratorStyle; +} + +void JKQTPGraphDecoratedLineStyleMixin::setHeadDecoratorSizeFactor(const double &__value) +{ + m_headDecoratorSizeFactor=__value; +} + +double JKQTPGraphDecoratedLineStyleMixin::getHeadDecoratorSizeFactor() const +{ + return m_headDecoratorSizeFactor; +} + +void JKQTPGraphDecoratedLineStyleMixin::setTailDecoratorSizeFactor(const double &__value) +{ + m_tailDecoratorSizeFactor=__value; +} + +double JKQTPGraphDecoratedLineStyleMixin::getTailDecoratorSizeFactor() const +{ + return m_tailDecoratorSizeFactor; +} diff --git a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h index 2bd5be012e..1057e72e16 100644 --- a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h +++ b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h @@ -145,6 +145,59 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGraphLineStyleMixin { +/*! \brief This Mix-In class provides setter/getter methods, storage and other facilities for the graph line style of lines + with decorators (i.e. arrows) at their ends. It extends JKQTPGraphLineStyleMixin + \ingroup jkqtplotter_basegraphs_stylemixins + + supported properties: + - head/tail arrow style + . +*/ +class JKQTPLOTTER_LIB_EXPORT JKQTPGraphDecoratedLineStyleMixin: public JKQTPGraphLineStyleMixin { + Q_GADGET +public: + /** \brief class constructor */ + JKQTPGraphDecoratedLineStyleMixin(); + /** \brief initiaize the line style (from the parent plotter) */ + void initDecoratedLineStyle(JKQTBasePlotter *parent, int &parentPlotStyle); + + virtual ~JKQTPGraphDecoratedLineStyleMixin(); + + /** \brief set the head decorator style */ + void setHeadDecoratorStyle(const JKQTPLineDecoratorStyle & __value); + /** \brief get the head decorator style */ + JKQTPLineDecoratorStyle getHeadDecoratorStyle() const; + /** \brief set the tail decorator style */ + void setTailDecoratorStyle(const JKQTPLineDecoratorStyle & __value); + /** \brief get the tail decorator style */ + JKQTPLineDecoratorStyle getTailDecoratorStyle() const; + + /** \copydoc m_headDecoratorSizeFactor */ + void setHeadDecoratorSizeFactor(const double & __value); + /** \copydoc m_headDecoratorSizeFactor */ + double getHeadDecoratorSizeFactor() const; + /** \copydoc m_tailDecoratorSizeFactor */ + void setTailDecoratorSizeFactor(const double & __value); + /** \copydoc m_tailDecoratorSizeFactor */ + double getTailDecoratorSizeFactor() const; + + + + Q_PROPERTY(JKQTPLineDecoratorStyle headDecoratorStyle MEMBER m_headDecoratorStyle READ getHeadDecoratorStyle WRITE setHeadDecoratorStyle) + Q_PROPERTY(JKQTPLineDecoratorStyle tailDecoratorStyle MEMBER m_tailDecoratorStyle READ getTailDecoratorStyle WRITE setTailDecoratorStyle) + Q_PROPERTY(double headDecoratorSizeFactor MEMBER m_headDecoratorSizeFactor READ getHeadDecoratorSizeFactor WRITE setHeadDecoratorSizeFactor) + Q_PROPERTY(double tailDecoratorSizeFactor MEMBER m_tailDecoratorSizeFactor READ getTailDecoratorSizeFactor WRITE setTailDecoratorSizeFactor) +private: + /** \brief head decorator style */ + JKQTPLineDecoratorStyle m_headDecoratorStyle; + /** \brief tail decorator style */ + JKQTPLineDecoratorStyle m_tailDecoratorStyle; + /** \brief head decorator size-factor, used to calculate the size of the arrow from the line width */ + double m_headDecoratorSizeFactor; + /** \brief tail decorator size-factor, used to calculate the size of the arrow from the line width */ + double m_tailDecoratorSizeFactor; +}; + diff --git a/screenshots/geometric.png b/screenshots/geometric.png index fbce179bcb..d779cf624c 100644 Binary files a/screenshots/geometric.png and b/screenshots/geometric.png differ diff --git a/screenshots/geometric_small.png b/screenshots/geometric_small.png index ec0797a658..edb074e2d1 100644 Binary files a/screenshots/geometric_small.png and b/screenshots/geometric_small.png differ