diff --git a/doc/dox/examples_and_tutorials.dox b/doc/dox/examples_and_tutorials.dox index d5fa7a8353..f3c50e856c 100644 --- a/doc/dox/examples_and_tutorials.dox +++ b/doc/dox/examples_and_tutorials.dox @@ -56,9 +56,6 @@ All test-projects are Qt-projects that use qmake to build. You can load them int \image html parsedfunctionplot_small.png \subpage JKQTPlotterParsedFunctionPlot `JKQTPXParsedFunctionLineGraph`
plotting functions with the internal math equation parser/evaluator - \image html geometric_small.png - \subpage JKQTPlotterGeometricGraphs - `JKQTPPlotObject`, `JKQTPGeoArc`, `JKQTPGeoLine`, `JKQTPGeoRectangle`, ... \image html boxplot_small.png \subpage JKQTPlotterBoxplotsGraphs `JKQTPBoxplotVerticalGraph`, `JKQTPBoxplotHorizontalGraph`, ... @@ -68,6 +65,18 @@ All test-projects are Qt-projects that use qmake to build. You can load them int +\subsection jkqtp_extut_geometric Geometric Forms, Arrows, Annotaions ... + + +
Screenshot Description Notes +
\image html geometric_small.png + \subpage JKQTPlotterGeometricGraphs + `JKQTPPlotObject`, `JKQTPGeoArc`, `JKQTPGeoLine`, `JKQTPGeoRectangle`, ... +
\image html geo_arrows_small.png + \subpage JKQTPlotterGeometricArrows + `JKQTPGeoArrow`, ... +
+ \subsection jkqtp_extut_keyaxesstyles Styling the Plot, Keys, Axes, ... diff --git a/doc/dox/jkqtplotter.dox b/doc/dox/jkqtplotter.dox index 60dc74ee15..af030660d0 100644 --- a/doc/dox/jkqtplotter.dox +++ b/doc/dox/jkqtplotter.dox @@ -429,7 +429,7 @@ 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 + \image html geo_arrows_small.png JKQTPGeoArrow
\image html geo_rect_small.png diff --git a/doc/images/JKQTPArrow.png b/doc/images/JKQTPArrow.png index f94a4e24f8..2677afc59d 100644 Binary files a/doc/images/JKQTPArrow.png and b/doc/images/JKQTPArrow.png differ diff --git a/doc/images/JKQTPArrowAndBar.png b/doc/images/JKQTPArrowAndBar.png new file mode 100644 index 0000000000..8ce42bb12b Binary files /dev/null and b/doc/images/JKQTPArrowAndBar.png differ diff --git a/doc/images/JKQTPArrowAndStop.png b/doc/images/JKQTPArrowAndStop.png deleted file mode 100644 index 0b1e3555db..0000000000 Binary files a/doc/images/JKQTPArrowAndStop.png and /dev/null differ diff --git a/doc/images/JKQTPBarDecorator.png b/doc/images/JKQTPBarDecorator.png new file mode 100644 index 0000000000..5072802fba Binary files /dev/null and b/doc/images/JKQTPBarDecorator.png differ diff --git a/doc/images/JKQTPBracketDecorator.png b/doc/images/JKQTPBracketDecorator.png index 831afd550b..522ab77465 100644 Binary files a/doc/images/JKQTPBracketDecorator.png and b/doc/images/JKQTPBracketDecorator.png differ diff --git a/doc/images/JKQTPCircleDecorator.png b/doc/images/JKQTPCircleDecorator.png index af91d02628..02abe59c0b 100644 Binary files a/doc/images/JKQTPCircleDecorator.png and b/doc/images/JKQTPCircleDecorator.png differ diff --git a/doc/images/JKQTPDiamondDecorator.png b/doc/images/JKQTPDiamondDecorator.png new file mode 100644 index 0000000000..b4916e243a Binary files /dev/null and b/doc/images/JKQTPDiamondDecorator.png differ diff --git a/doc/images/JKQTPDiamondDecoratorAndBar.png b/doc/images/JKQTPDiamondDecoratorAndBar.png new file mode 100644 index 0000000000..bc6d7fb6ac Binary files /dev/null and b/doc/images/JKQTPDiamondDecoratorAndBar.png differ diff --git a/doc/images/JKQTPDoubleArrow.png b/doc/images/JKQTPDoubleArrow.png index 7c47f888d9..598fabc033 100644 Binary files a/doc/images/JKQTPDoubleArrow.png and b/doc/images/JKQTPDoubleArrow.png differ diff --git a/doc/images/JKQTPDoubleArrowAndBar.png b/doc/images/JKQTPDoubleArrowAndBar.png new file mode 100644 index 0000000000..cb91566df2 Binary files /dev/null and b/doc/images/JKQTPDoubleArrowAndBar.png differ diff --git a/doc/images/JKQTPDoubleArrowAndStop.png b/doc/images/JKQTPDoubleArrowAndStop.png deleted file mode 100644 index 084c16d6c3..0000000000 Binary files a/doc/images/JKQTPDoubleArrowAndStop.png and /dev/null differ diff --git a/doc/images/JKQTPFilledArrow.png b/doc/images/JKQTPFilledArrow.png index 5bfa6ce4a6..5c42fd9f2c 100644 Binary files a/doc/images/JKQTPFilledArrow.png and b/doc/images/JKQTPFilledArrow.png differ diff --git a/doc/images/JKQTPFilledCircleDecorator.png b/doc/images/JKQTPFilledCircleDecorator.png index 6a576ab307..63323149db 100644 Binary files a/doc/images/JKQTPFilledCircleDecorator.png and b/doc/images/JKQTPFilledCircleDecorator.png differ diff --git a/doc/images/JKQTPFilledDiamondDecorator.png b/doc/images/JKQTPFilledDiamondDecorator.png new file mode 100644 index 0000000000..a7ea0a7f5e Binary files /dev/null and b/doc/images/JKQTPFilledDiamondDecorator.png differ diff --git a/doc/images/JKQTPFilledDiamondDecoratorAndBar.png b/doc/images/JKQTPFilledDiamondDecoratorAndBar.png new file mode 100644 index 0000000000..73f951e7ef Binary files /dev/null and b/doc/images/JKQTPFilledDiamondDecoratorAndBar.png differ diff --git a/doc/images/JKQTPFilledDoubleArrow.png b/doc/images/JKQTPFilledDoubleArrow.png index d4967b6693..d5069120f4 100644 Binary files a/doc/images/JKQTPFilledDoubleArrow.png and b/doc/images/JKQTPFilledDoubleArrow.png differ diff --git a/doc/images/JKQTPFilledRectangleDecorator.png b/doc/images/JKQTPFilledRectangleDecorator.png index d26a33ae8c..bd59951909 100644 Binary files a/doc/images/JKQTPFilledRectangleDecorator.png and b/doc/images/JKQTPFilledRectangleDecorator.png differ diff --git a/doc/images/JKQTPFilledTriangleDecorator.png b/doc/images/JKQTPFilledTriangleDecorator.png index bf4a75a429..379d358928 100644 Binary files a/doc/images/JKQTPFilledTriangleDecorator.png and b/doc/images/JKQTPFilledTriangleDecorator.png differ diff --git a/doc/images/JKQTPFilledTriangleDecoratorAndBar.png b/doc/images/JKQTPFilledTriangleDecoratorAndBar.png new file mode 100644 index 0000000000..d2fcdec37d Binary files /dev/null and b/doc/images/JKQTPFilledTriangleDecoratorAndBar.png differ diff --git a/doc/images/JKQTPGeoLine_HeadTail.png b/doc/images/JKQTPGeoLine_HeadTail.png new file mode 100644 index 0000000000..6ab4a7916e Binary files /dev/null and b/doc/images/JKQTPGeoLine_HeadTail.png differ diff --git a/doc/images/JKQTPHalfBarDecorator.png b/doc/images/JKQTPHalfBarDecorator.png new file mode 100644 index 0000000000..d00f93e102 Binary files /dev/null and b/doc/images/JKQTPHalfBarDecorator.png differ diff --git a/doc/images/JKQTPHarpoonDecorator.png b/doc/images/JKQTPHarpoonDecorator.png new file mode 100644 index 0000000000..6090e6c1e6 Binary files /dev/null and b/doc/images/JKQTPHarpoonDecorator.png differ diff --git a/doc/images/JKQTPHarpoonDecoratorAndBar.png b/doc/images/JKQTPHarpoonDecoratorAndBar.png new file mode 100644 index 0000000000..e5a433ec25 Binary files /dev/null and b/doc/images/JKQTPHarpoonDecoratorAndBar.png differ diff --git a/doc/images/JKQTPNoDecorator.png b/doc/images/JKQTPNoDecorator.png new file mode 100644 index 0000000000..ae97b0b7c5 Binary files /dev/null and b/doc/images/JKQTPNoDecorator.png differ diff --git a/doc/images/JKQTPRectangleDecorator.png b/doc/images/JKQTPRectangleDecorator.png index af32738b93..6e41cfe8e4 100644 Binary files a/doc/images/JKQTPRectangleDecorator.png and b/doc/images/JKQTPRectangleDecorator.png differ diff --git a/doc/images/JKQTPSkewedBarDecorator.png b/doc/images/JKQTPSkewedBarDecorator.png new file mode 100644 index 0000000000..a5cd7c6df3 Binary files /dev/null and b/doc/images/JKQTPSkewedBarDecorator.png differ diff --git a/doc/images/JKQTPTriangleDecorator.png b/doc/images/JKQTPTriangleDecorator.png index e53ae711e4..3d12b0d9f0 100644 Binary files a/doc/images/JKQTPTriangleDecorator.png and b/doc/images/JKQTPTriangleDecorator.png differ diff --git a/doc/images/JKQTPTriangleDecoratorAndBar.png b/doc/images/JKQTPTriangleDecoratorAndBar.png new file mode 100644 index 0000000000..72ab8a77a0 Binary files /dev/null and b/doc/images/JKQTPTriangleDecoratorAndBar.png differ diff --git a/doc/images/JKQTPTriangleDecoratorAndStop.png b/doc/images/JKQTPTriangleDecoratorAndStop.png deleted file mode 100644 index 5f7d140ae5..0000000000 Binary files a/doc/images/JKQTPTriangleDecoratorAndStop.png and /dev/null differ diff --git a/doc/images/JKQTPVerticalDecorator.png b/doc/images/JKQTPVerticalDecorator.png deleted file mode 100644 index 265ecb3d52..0000000000 Binary files a/doc/images/JKQTPVerticalDecorator.png and /dev/null differ diff --git a/doc/images/geo_arrow_inflines.png b/doc/images/geo_arrow_inflines.png new file mode 100644 index 0000000000..2b7917859e Binary files /dev/null and b/doc/images/geo_arrow_inflines.png differ diff --git a/doc/images/geo_arrow_polylines.png b/doc/images/geo_arrow_polylines.png new file mode 100644 index 0000000000..bba384be18 Binary files /dev/null and b/doc/images/geo_arrow_polylines.png differ diff --git a/doc/images/geo_arrow_small.png b/doc/images/geo_arrow_small.png index 7bb9802541..8b6439c29e 100644 Binary files a/doc/images/geo_arrow_small.png and b/doc/images/geo_arrow_small.png differ diff --git a/doc/images/geo_arrow_tips.png b/doc/images/geo_arrow_tips.png new file mode 100644 index 0000000000..ac4cb6ed87 Binary files /dev/null and b/doc/images/geo_arrow_tips.png differ diff --git a/doc/images/geo_arrow_tipsatlineend.png b/doc/images/geo_arrow_tipsatlineend.png new file mode 100644 index 0000000000..7920c52e1c Binary files /dev/null and b/doc/images/geo_arrow_tipsatlineend.png differ diff --git a/doc/images/plot_geoarrows.png b/doc/images/plot_geoarrows.png index 554c7b68d9..144ef44d6e 100644 Binary files a/doc/images/plot_geoarrows.png and b/doc/images/plot_geoarrows.png differ diff --git a/doc/images/plot_geoinfiniteline.png b/doc/images/plot_geoinfiniteline.png index be6e8334cb..a1b9896acb 100644 Binary files a/doc/images/plot_geoinfiniteline.png and b/doc/images/plot_geoinfiniteline.png differ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 23b995b032..3aaae13148 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -12,6 +12,7 @@ add_subdirectory(jkqtmathtext_test) add_subdirectory(jkqtplot_test) +add_subdirectory(geo_arrows) add_subdirectory(advplotstyling) add_subdirectory(barchart) add_subdirectory(boxplot) diff --git a/examples/README.md b/examples/README.md index aecc9e2fa3..30698657c2 100644 --- a/examples/README.md +++ b/examples/README.md @@ -22,12 +22,18 @@ All test-projects are Qt-projects that use qmake to build. You can load them int | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/parametriccurve_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/parametriccurve) | [Plotting Parametric Curves](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/parametriccurve) | `JKQTPXYLineGraph` and `JKQTPXYParametrizedScatterGraph`
C++-style QVector as plot data
parametric curve plotting | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/functionplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/functionplot) | [Plotting Mathematical Functions as Line Graphs](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/functionplot) | `JKQTPXFunctionLineGraph`
diretly plotting C/C++-functions | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/parsedfunctionplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/parsedfunctionplot) | [Plotting Parsed Mathematical Functions as Line Graphs](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/parsedfunctionplot) | `JKQTPXParsedFunctionLineGraph`
plotting functions with the internal math equation parser/evaluator | -| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/geometric_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/geometric) | [Plotting Geometric Objects](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/geometric) | | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/boxplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/boxplot) | [Plotting Box Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/boxplot) | `JKQTPBoxplotVerticalGraph`, `JKQTPBoxplotHorizontalGraph` | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/violinplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/violinplot) | [Plotting Violin Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/violinplot) | `JKQTPViolinplotVerticalElement`, `JKQTPViolinplotHorizontalElement` | ## Styling the Plot, Keys, Axes, ... +| Screenshot | Description | Notes | +|:-------------:| ------------- | ------------- | +| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/geometric_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/geometric) | [Plotting Geometric Objects](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/geometric) | | +| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/geo_arrows_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/geo_arrows) | [Plotting Arrows](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/geo_arrows) | | + +## Styling the Plot, Keys, Axes, ... + | Screenshot | Description | Notes | |:-------------:| ------------- | ------------- | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/logaxes_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/logaxes) | [logarithmic axes](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/logaxes) | `JKQTPXYLineGraph` and `JKQTPGeoText`
C++ vector of data
logarithmic axes and styling
plot line styles
internal LaTeX parser
add commenting text to a graph | diff --git a/examples/geo_arrows/CMakeLists.txt b/examples/geo_arrows/CMakeLists.txt new file mode 100644 index 0000000000..777ce2f76d --- /dev/null +++ b/examples/geo_arrows/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.0) + +set(EXAMPLE_NAME geo_arrows) +set(EXENAME jkqtptest_${EXAMPLE_NAME}) + +message( STATUS ".. Building Example ${EXAMPLE_NAME}" ) + + +# Set up source files +set(SOURCES ${EXAMPLE_NAME}.cpp) +set(HEADERS ) +set(RESOURCES ) +set(UIS ) + +add_executable(${EXENAME} WIN32 ${SOURCES} ${HEADERS} ${RESOURCES} ${UIS}) +target_include_directories(${EXENAME} PRIVATE ../../lib) +if(JKQtPlotter_BUILD_STATIC_LIBS) + target_link_libraries(${EXENAME} JKQTPlotterLib) +elseif(JKQtPlotter_BUILD_SHARED_LIBS) + target_link_libraries(${EXENAME} JKQTPlotterSharedLib) +endif() + + + +# Installation +install(TARGETS ${EXENAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + +#Installation of Qt DLLs on Windows +jkqtplotter_deployqt(${EXENAME}) diff --git a/examples/geo_arrows/README.md b/examples/geo_arrows/README.md new file mode 100644 index 0000000000..5fcb6877d0 --- /dev/null +++ b/examples/geo_arrows/README.md @@ -0,0 +1,76 @@ +# Example (JKQTPlotter): Plotting Arrows {#JKQTPlotterGeometricArrows} + +This project shows the capabilities of JKQTPlotter to also draw arrows as geometric elements, using JKQTPGeoArrow. The arrow head/tail are defined by the enum values in JKQTPLineDecoratorStyle. + +The source code of the main application can be found in [`geo_arrows.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/geo_arrows/geo_arrows.cpp). First a plot is generated. Then several types of arrows are plotted onto the JKQtPlotter. + +## Different types of arrows + +A first table shows all available arrow tips in different sizes. +```.cpp + for (size_t i=0; i(JKQTPLineDecoratorCount); i++) { + auto const decor=static_cast(i); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.1, arr_y, 0.3, arr_y+0.05, QColor("red"), decor, JKQTPNoDecorator, 0.2)); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.4, arr_y, 0.6, arr_y+0.05, QColor("red"), decor, JKQTPNoDecorator, 0.5)); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.7, arr_y, 0.9, arr_y+0.05, QColor("red"), decor, JKQTPNoDecorator, 1)); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 1.0, arr_y, 1.3, arr_y+0.05, QColor("red"), decor, JKQTPNoDecorator, 2)); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 1.4, arr_y, 1.7, arr_y+0.05, QColor("red"), decor, JKQTPNoDecorator, 3)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.05, a->getY2(), "\\verb{"+JKQTPLineDecoratorStyle2String(decor)+"}", 12, a->getLineColor())); + arr_y+=arr_deltay; + } +``` + +Here is the resulting table: + +![geo_arrow_tips](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/doc/images/geo_arrow_tips.png) + +Note how the head-size scales with the line-width, but not linearly, but rather sub-linearly, so the tips do not grow too strongly. + +Also note that all arrows end at the designated line-end (here indicated by dashed grey lines), even circles and rectangle: + +![geo_arrow_tipsatlineend](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/doc/images/geo_arrow_tipsatlineend.png) + +## Classes with support for arrows + +You can use JKQTPGeoArrow and JKQTPGeoLine to draw arrows (JKQTPGeoArrow is just a convenience class that enables arrows by default, otherwise it is equal to JKQTPGeoLine). + +In addition, also other classes can show line-decorators: + - JKQTPGeoLine + - JKQTPGeoPolyLines + - JKQTPGeoInfiniteLine +. + +Here is an example of how to actiavate them for a JKQTPGeoPolyLines: + +```.cpp + QVector points; points<setHeadDecoratorStyle(JKQTPFilledDoubleArrow); + polyLine->setTailDecoratorStyle(JKQTPCircleDecorator); + plot.addGraph(polyLine); +``` + +Here is the result: + +![geo_arrow_polylines](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/doc/images/geo_arrow_polylines.png) + +For the class JKQTPGeoInfiniteLine the start can be decorated with an arrow (only if two_sided==false!): + +```.cpp + JKQTPGeoInfiniteLine* infLine=new JKQTPGeoInfiniteLine(&plot, 1.5, 0.2, 1, 0.25, QColor("blue"), 2); + infLine->setHeadDecoratorStyle(JKQTPFilledDoubleArrow); + plot.addGraph(infLine); +``` + +Here is the result: + +![geo_arrow_polylines](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/doc/images/geo_arrow_inflines.png) + +## Screenshot + +The result of the complete example looks like this: + +![geo_arrows](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/geo_arrows.png) + + + diff --git a/examples/geo_arrows/geo_arrows.cpp b/examples/geo_arrows/geo_arrows.cpp new file mode 100644 index 0000000000..24d228881a --- /dev/null +++ b/examples/geo_arrows/geo_arrows.cpp @@ -0,0 +1,103 @@ +/** \example geo_arrows.cpp + * Shows how to plot arrows as geometric elements with JKQTPlotter + * + * \ref JKQTPlotterGeometricArrows + */ + +#include +#include "jkqtplotter/jkqtplotter.h" +#include "jkqtplotter/graphs/jkqtpgeometric.h" + + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + + // 1. create a plotter window + JKQTPlotter plot; + + // 2. format graph: + // 2.1 set the graph scales manually + plot.setXY(0,4.05,0,3.15); + // 2.2 set the asxpect ratio to 1 + plot.getPlotter()->setMaintainAspectRatio(true); + plot.getPlotter()->setAspectRatio(4.05/3.05); + plot.getPlotter()->setMaintainAxisAspectRatio(true); + plot.getPlotter()->setAxisAspectRatio(4.05/3.05); + // 2.3 set the asxpect ratio to 1 + plot.getXAxis()->setDrawGrid(false); + plot.getYAxis()->setDrawGrid(false); + + + // 3.1 demonastrate all arrow heads + JKQTPGeoArrow* a; + double arr_y=0.1; + double arr_deltay=2.9/static_cast(JKQTPLineDecoratorCount); + plot.addGraph(new JKQTPGeoText(&plot, 0.1, 3.0, "w_{line}=0.2", 12, QColor("darkred"))); + plot.addGraph(new JKQTPGeoText(&plot, 0.4, 3.0, "w_{line}=0.5", 12, QColor("darkred"))); + plot.addGraph(new JKQTPGeoText(&plot, 0.7, 3.0, "w_{line}=1", 12, QColor("darkred"))); + plot.addGraph(new JKQTPGeoText(&plot, 1.0, 3.0, "w_{line}=2", 12, QColor("darkred"))); + plot.addGraph(new JKQTPGeoText(&plot, 1.4, 3.0, "w_{line}=3", 12, QColor("darkred"))); + for (size_t i=0; i(JKQTPLineDecoratorCount); i++) { + auto const decor=static_cast(i); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.1, arr_y, 0.3, arr_y+0.05, QColor("red"), decor, JKQTPNoDecorator, 0.2)); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.4, arr_y, 0.6, arr_y+0.05, QColor("red"), decor, JKQTPNoDecorator, 0.5)); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 0.7, arr_y, 0.9, arr_y+0.05, QColor("red"), decor, JKQTPNoDecorator, 1)); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 1.0, arr_y, 1.3, arr_y+0.05, QColor("red"), decor, JKQTPNoDecorator, 2)); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 1.4, arr_y, 1.7, arr_y+0.05, QColor("red"), decor, JKQTPNoDecorator, 3)); + plot.addGraph(new JKQTPGeoText(&plot, a->getX2()+0.05, a->getY2(), "\\verb{"+JKQTPLineDecoratorStyle2String(decor)+"}", 12, a->getLineColor())); + arr_y+=arr_deltay; + } + + // 3.2 note that all decorators are drawn in a way that lets them end at the intended end-point of the line, even circles! + for (size_t i=0; i<6; i++) { + plot.addGraph(a=new JKQTPGeoArrow(&plot, 3+static_cast(i)*0.15, 3, 3+static_cast(i)*0.15, 2.75, QColor("blue"), static_cast(i*4+1), static_cast(i*4+2), static_cast(i+1)*0.5)); + plot.addGraph(a=new JKQTPGeoArrow(&plot, 3+static_cast(i)*0.15, 2.5, 3+static_cast(i)*0.15, 2.75, QColor("red"), static_cast(i*4+3), static_cast(i*4+4), static_cast(i+1)*0.5)); + } + plot.addGraph(new JKQTPGeoLine(&plot, 2.9, 2.5, 4.0, 2.5, QColor("silver"), 0.25, Qt::DashLine)); + plot.addGraph(new JKQTPGeoLine(&plot, 2.9, 2.75, 4.0, 2.75, QColor("silver"), 0.25, Qt::DashLine)); + plot.addGraph(new JKQTPGeoLine(&plot, 2.9, 3, 4.6, 3, QColor("silver"), 0.25, Qt::DashLine)); + + // 3.3 a JKQTPGeoLine with and without errow heads: + JKQTPGeoLine* line=new JKQTPGeoLine(&plot, 2.9, 2.3, 3.6, 2.4, QColor("red"), 2.0); + JKQTPGeoLine* line_heads=new JKQTPGeoLine(&plot, 2.9, 2.1, 3.6, 2.2, QColor("red"), 2.0); + line_heads->setHeadDecoratorStyle(JKQTPFilledDoubleArrow); + line_heads->setTailDecoratorStyle(JKQTPCircleDecorator); + plot.addGraph(line); + plot.addGraph(line_heads); + plot.addGraph(new JKQTPGeoSymbol(&plot, line->getX1(), line->getY1(), JKQTPCirclePlus, 8, QColor("silver"))); + plot.addGraph(new JKQTPGeoSymbol(&plot, line->getX2(), line->getY2(), JKQTPCirclePlus, 8, QColor("silver"))); + plot.addGraph(new JKQTPGeoSymbol(&plot, line_heads->getX1(), line_heads->getY1(), JKQTPCirclePlus, 8, QColor("silver"))); + plot.addGraph(new JKQTPGeoSymbol(&plot, line_heads->getX2(), line_heads->getY2(), JKQTPCirclePlus, 8, QColor("silver"))); + + + // 3.4 also the class JKQTPGeoPolyLines can decorate its start/end with arrows + QVector points; points<setHeadDecoratorStyle(JKQTPFilledDoubleArrow); + polyLine->setTailDecoratorStyle(JKQTPCircleDecorator); + plot.addGraph(polyLine); + + + // 3.5 also the class JKQTPGeoInfiniteLine can decorate its start with arrows (only if two_sided==false!) + JKQTPGeoInfiniteLine* infLine=new JKQTPGeoInfiniteLine(&plot, 3.5, 0.2, 1, 0.25, QColor("blue"), 2); + infLine->setHeadDecoratorStyle(JKQTPFilledDoubleArrow); + plot.addGraph(infLine); + plot.addGraph(new JKQTPGeoSymbol(&plot, infLine->getX(), infLine->getY(), JKQTPCirclePlus, 8, QColor("silver"))); + plot.addGraph(new JKQTPGeoArrow(&plot, infLine->getX(), infLine->getY(), infLine->getX()+infLine->getDx(), infLine->getY()+infLine->getDy(), QColor("silver"), JKQTPArrow, JKQTPNoDecorator, 1)); +/* + infLine=new JKQTPGeoInfiniteLine(&plot, 3.5, 0.1, -1, 0.25, QColor("darkblue"), 2); + infLine->setHeadDecoratorStyle(JKQTPFilledDoubleArrow); + infLine->setTwoSided(true); + plot.addGraph(infLine); + plot.addGraph(new JKQTPGeoSymbol(&plot, infLine->getX(), infLine->getY(), JKQTPCirclePlus, 8, QColor("silver"))); + plot.addGraph(new JKQTPGeoArrow(&plot, infLine->getX(), infLine->getY(), infLine->getX()+infLine->getDx(), infLine->getY()+infLine->getDy(), QColor("silver"), JKQTPArrow, JKQTPNoDecorator, 1)); +*/ + + + // 4. show plotter and make it a decent size + plot.show(); + plot.resize(1200,800); + + return app.exec(); +} diff --git a/examples/geo_arrows/geo_arrows.pro b/examples/geo_arrows/geo_arrows.pro new file mode 100644 index 0000000000..4ba64d82a0 --- /dev/null +++ b/examples/geo_arrows/geo_arrows.pro @@ -0,0 +1,27 @@ +# source code for this simple demo +SOURCES = geo_arrows.cpp + +# configure Qt +CONFIG += link_prl qt +QT += core gui xml svg +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport + +# output executable name +TARGET = geo_arrows + +# include JKQTPlotter source code +DEPENDPATH += ../../lib ../../staticlib +INCLUDEPATH += ../../lib +CONFIG (debug, debug|release) { + LIBS += -L../../qmake/staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug +} else { + LIBS += -L../../qmake/staticlib/jkqtplotterlib/release -ljkqtplotterlib +} +message("LIBS = $$LIBS") + +win32-msvc*: DEFINES += _USE_MATH_DEFINES +win32-msvc*: DEFINES += NOMINMAX + + + + diff --git a/examples/geo_arrows/geo_arrows_and_lib.pro b/examples/geo_arrows/geo_arrows_and_lib.pro new file mode 100644 index 0000000000..cf29385de3 --- /dev/null +++ b/examples/geo_arrows/geo_arrows_and_lib.pro @@ -0,0 +1,8 @@ +TEMPLATE = subdirs + +SUBDIRS += jkqtplotterlib geo_arrows + +jkqtplotterlib.file = ../../qmake/staticlib/jkqtplotterlib/jkqtplotterlib.pro + +geo_arrows.file=$$PWD/geo_arrows.pro +geo_arrows.depends = jkqtplotterlib diff --git a/examples/geometric/geometric.cpp b/examples/geometric/geometric.cpp index 6322875e55..64405a271c 100644 --- a/examples/geometric/geometric.cpp +++ b/examples/geometric/geometric.cpp @@ -59,79 +59,21 @@ int main(int argc, char* argv[]) // 3.3 some arrows plot.addGraph(new JKQTPGeoText(&plot, 0.1,2.95, "\\textbf{Arrows:}", 14, QColor("red"))); - 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.3, 2.1, 0.1, 2.9, QColor("green"), JKQTPTriangleDecoratorAndBar, JKQTPDiamondDecoratorAndBar, 1)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.2, 2.1, 0.2, 2.9, QColor("blue"), JKQTPNoDecorator, JKQTPFilledTriangleDecoratorAndBar, 2)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.1, 2.1, 0.3, 2.9, QColor("orange"), JKQTPDoubleArrowAndBar, JKQTPNoDecorator, 3)); - 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.9, QColor("green"), JKQTPTriangleDecorator, JKQTPTriangleDecorator, 0.5)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.5, 2.1, 0.5, 2.9, QColor("blue"), JKQTPNoDecorator, JKQTPFilledArrow, 2)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.4, 2.1, 0.6, 2.9, QColor("orange"), JKQTPFilledArrow, JKQTPNoDecorator, 1)); - 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.7, 2.1, 0.7, 2.5, QColor("green"), JKQTPArrowAndBar, JKQTPFilledArrow, 0.5)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.8, 2.1, 0.8, 2.5, QColor("orange"), JKQTPArrowAndBar, JKQTPFilledArrow, 1)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.9, 2.1, 0.9, 2.5, QColor("orange"), JKQTPArrowAndBar, JKQTPFilledArrow, 2)); - 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)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.7, 2.7, 0.7, 2.9, QColor("green"), JKQTPTriangleDecoratorAndBar, JKQTPFilledCircleDecorator, 0.5)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.8, 2.7, 0.8, 2.9, QColor("orange"), JKQTPTriangleDecoratorAndBar, JKQTPFilledCircleDecorator, 1)); + plot.addGraph(new JKQTPGeoArrow(&plot, 0.9, 2.7, 0.9, 2.9, QColor("orange"), JKQTPTriangleDecoratorAndBar, JKQTPFilledCircleDecorator, 2)); diff --git a/lib/jkqtcommon/jkqtpdrawingtools.cpp b/lib/jkqtcommon/jkqtpdrawingtools.cpp index 422569fc8a..ff16aa4d10 100644 --- a/lib/jkqtcommon/jkqtpdrawingtools.cpp +++ b/lib/jkqtcommon/jkqtpdrawingtools.cpp @@ -413,18 +413,26 @@ QString JKQTPLineDecoratorStyle2String(JKQTPLineDecoratorStyle pos) case JKQTPFilledArrow: return "filled_arrow"; case JKQTPTriangleDecorator: return "triangle"; case JKQTPFilledTriangleDecorator: return "filled_triangle"; - case JKQTPTriangleDecoratorAndStop: return "triangle_stop"; - case JKQTPFilledTriangleDecoratorAndStop: return "filled_triangle_stop"; + case JKQTPTriangleDecoratorAndBar: return "triangle_bar"; + case JKQTPFilledTriangleDecoratorAndBar: return "filled_triangle_bar"; case JKQTPDoubleArrow: return "double_arrow"; case JKQTPFilledDoubleArrow: return "filled_double_arrow"; case JKQTPCircleDecorator: return "circle"; case JKQTPFilledCircleDecorator: return "filled_circle"; case JKQTPRectangleDecorator: return "rectangle"; case JKQTPFilledRectangleDecorator: return "filled_rectangle"; - case JKQTPArrowAndStop: return "arrow_stop"; - case JKQTPDoubleArrowAndStop: return "double_arrow_stop"; - case JKQTPVerticalDecorator: return "vertical_line"; + case JKQTPArrowAndBar: return "arrow_bar"; + case JKQTPDoubleArrowAndBar: return "double_arrow_bar"; + case JKQTPBarDecorator: return "bar"; case JKQTPBracketDecorator: return "bracket"; + case JKQTPHalfBarDecorator: return "half_bar"; + case JKQTPSkewedBarDecorator: return "skewed_bar"; + case JKQTPHarpoonDecorator: return "harpoon"; + case JKQTPHarpoonDecoratorAndBar: return "harpoon_bar"; + case JKQTPDiamondDecorator: return "diamond"; + case JKQTPFilledDiamondDecorator: return "filled_diamond"; + case JKQTPDiamondDecoratorAndBar: return "diamond_bar"; + case JKQTPFilledDiamondDecoratorAndBar: return "filled_diamond_bar"; case JKQTPLineDecoratorCount: JKQTPLineDecoratorStyle2String(JKQTPMaxLineDecoratorID); } return ""; @@ -438,17 +446,25 @@ QString JKQTPLineDecoratorStyle2NameString(JKQTPLineDecoratorStyle pos) case JKQTPFilledArrow: return QObject::tr("filled arrow"); case JKQTPTriangleDecorator: return QObject::tr("triangle"); case JKQTPFilledTriangleDecorator: return QObject::tr("filled triangle"); - case JKQTPTriangleDecoratorAndStop: return QObject::tr("triangle with stop"); - case JKQTPFilledTriangleDecoratorAndStop: return QObject::tr("filled triangle with stop"); + case JKQTPTriangleDecoratorAndBar: return QObject::tr("triangle, with bar"); + case JKQTPFilledTriangleDecoratorAndBar: return QObject::tr("filled triangle, with bar"); case JKQTPDoubleArrow: return QObject::tr("double arrow"); case JKQTPFilledDoubleArrow: return QObject::tr("filled double arrow"); case JKQTPCircleDecorator: return QObject::tr("circle"); case JKQTPFilledCircleDecorator: return QObject::tr("filled circle"); case JKQTPRectangleDecorator: return QObject::tr("rectangle"); case JKQTPFilledRectangleDecorator: return QObject::tr("filled rectangle"); - case JKQTPArrowAndStop: return QObject::tr("arrow with stop"); - case JKQTPDoubleArrowAndStop: return QObject::tr("double arrow with stop"); - case JKQTPVerticalDecorator: return QObject::tr("vertical line"); + case JKQTPArrowAndBar: return QObject::tr("arrow, with bar"); + case JKQTPDoubleArrowAndBar: return QObject::tr("double arrow, with bar"); + case JKQTPBarDecorator: return QObject::tr("full bar"); + case JKQTPHalfBarDecorator: return QObject::tr("half bar"); + case JKQTPSkewedBarDecorator: return QObject::tr("skewed bar"); + case JKQTPHarpoonDecorator: return QObject::tr("harpoon"); + case JKQTPHarpoonDecoratorAndBar: return QObject::tr("harpoon, with bar"); + case JKQTPDiamondDecorator: return QObject::tr("diamond"); + case JKQTPFilledDiamondDecorator: return QObject::tr("filled diamond"); + case JKQTPDiamondDecoratorAndBar: return QObject::tr("diamond, with bar"); + case JKQTPFilledDiamondDecoratorAndBar: return QObject::tr("filled diamond, with bar"); case JKQTPBracketDecorator: return QObject::tr("bracket"); case JKQTPLineDecoratorCount: JKQTPLineDecoratorStyle2NameString(JKQTPMaxLineDecoratorID); } @@ -463,18 +479,32 @@ JKQTPLineDecoratorStyle String2JKQTPLineDecoratorStyle(const QString &pos) 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=="triangle_bar") return JKQTPTriangleDecoratorAndBar; + if (s=="filled_triangle_bar") return JKQTPFilledTriangleDecoratorAndBar; 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=="arrow_bar") return JKQTPArrowAndBar; + if (s=="double_arrow_bar") return JKQTPDoubleArrowAndBar; + if (s=="bar" || s=="vertical_line") return JKQTPBarDecorator; + if (s=="half_bar") return JKQTPHalfBarDecorator; + if (s=="skewed_bar") return JKQTPSkewedBarDecorator; + if (s=="harpoon") return JKQTPHarpoonDecorator; + if (s=="harpoon_bar") return JKQTPHarpoonDecoratorAndBar; + if (s=="diamond") return JKQTPDiamondDecorator; + if (s=="filled_diamond") return JKQTPFilledDiamondDecorator; + if (s=="diamond_bar") return JKQTPDiamondDecoratorAndBar; + if (s=="filled_diamond_bar") return JKQTPFilledDiamondDecoratorAndBar; if (s=="bracket") return JKQTPBracketDecorator; - return JKQTPNoDecorator; } + +double JKQTPLineDecoratorStyleCalcDecoratorSize(double line_width, double decoratorSizeFactor) +{ + if (line_width<=0.75) return 3.0+(decoratorSizeFactor*0.75-3.0)/(0.75*0.75)*line_width*line_width; + if (line_width<=1.0) return decoratorSizeFactor*line_width; + return decoratorSizeFactor*pow(line_width, 0.7); +} diff --git a/lib/jkqtcommon/jkqtpdrawingtools.h b/lib/jkqtcommon/jkqtpdrawingtools.h index 5b264b8794..4ca8149b6e 100644 --- a/lib/jkqtcommon/jkqtpdrawingtools.h +++ b/lib/jkqtcommon/jkqtpdrawingtools.h @@ -155,6 +155,14 @@ JKQTCOMMON_LIB_EXPORT JKQTPGraphSymbols String2JKQTPGraphSymbols(const QString& /** \brief symbols that can be used to plot a datapoint for a graph * \ingroup jkqtptools_drawing + * + * \image html geo_arrow_tips.png + * + * Note that all arrows end at the designated line-end (here indicated by dashed grey lines), even circles and rectangle: + * + * \image html geo_arrow_tipsatlineend.png + * + * \see \ref JKQTPlotterGeometricArrows and \ref JKQTPlotterGeometricGraphs */ enum JKQTPLineDecoratorStyle { JKQTPNoDecorator=0, /*!< \brief no decorator, i.e. a simple line-end */ @@ -162,21 +170,29 @@ enum JKQTPLineDecoratorStyle { 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 */ + JKQTPTriangleDecoratorAndBar, /*!< \brief a triangular arrow tip, with vertical bar \image html JKQTPTriangleDecoratorAndBar.png */ + JKQTPFilledTriangleDecoratorAndBar, /*!< \brief a triangular filled arrow tip, with vertical bar \image html JKQTPFilledTriangleDecoratorAndBar.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 */ + JKQTPArrowAndBar, /*!< \brief a simple arrow tip, unfilled, with vertical bar \image html JKQTPArrowAndBar.png */ + JKQTPDoubleArrowAndBar, /*!< \brief a simple double-arrow tip, unfilled, with vertical bar \image html JKQTPDoubleArrowAndBar.png */ + JKQTPBarDecorator, /*!< \brief a full vertical bar \image html JKQTPBarDecorator.png */ JKQTPBracketDecorator, /*!< \brief a vertical bracket decorator \image html JKQTPBracketDecorator.png */ + JKQTPDiamondDecorator, /*!< \brief an open diamond tip \image html JKQTPDiamondDecorator.png */ + JKQTPDiamondDecoratorAndBar, /*!< \brief an open diamond tip \image html JKQTPDiamondDecoratorAndBar.png */ + JKQTPFilledDiamondDecorator, /*!< \brief a filled diamond tip \image html JKQTPFilledDiamondDecorator.png */ + JKQTPFilledDiamondDecoratorAndBar, /*!< \brief a filled diamond tip \image html JKQTPFilledDiamondDecoratorAndBar.png */ + JKQTPHalfBarDecorator, /*!< \brief a half vertical bar \image html JKQTPHalfBarDecorator.png */ + JKQTPHarpoonDecorator, /*!< \brief an harpoon arrow \image html JKQTPHarpoonDecorator.png */ + JKQTPHarpoonDecoratorAndBar, /*!< \brief an harpoon arrow, with vertical bar \image html JKQTPHarpoonDecoratorAndBar.png */ + JKQTPSkewedBarDecorator, /*!< \brief a skewed vertical bar \image html JKQTPSkewedBarDecorator.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); ... } */ + JKQTPLineDecoratorCount, /*!< \brief can be used to iterate over all symbols using: for (int i=0; i(JKQTPLineDecoratorCount); 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(JKQTPMaxLineDecoratorID); i++) { JKQTPLineDecoratorStyle s=static_cast(i); ... } */ JKQTPDefaultLineDecorator=JKQTPFilledArrow /*!< \brief a default symbol used for plotting */ }; @@ -209,7 +225,9 @@ JKQTCOMMON_LIB_EXPORT JKQTPLineDecoratorStyle String2JKQTPLineDecoratorStyle(con template inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double angle_rad, JKQTPLineDecoratorStyle style, double size, QPointF* line_start=nullptr); - +/** \brief calculates the tail decorator size from the line width \a line_width, using decoratorSizeFactor and a non-linear scaling function that levels off towards small \a line_width and increases sub-linearly for large ones, so the arrow heads to not grow too much */ +JKQTCOMMON_LIB_EXPORT double JKQTPLineDecoratorStyleCalcDecoratorSize(double line_width, double decoratorSizeFactor) +; /** \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 @@ -923,7 +941,9 @@ inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double 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 pinit=painter.pen(); + pinit.setCapStyle(Qt::FlatCap); + pinit.setJoinStyle(Qt::RoundJoin); QPen p0=pinit; p0.setWidthF(0); { @@ -934,25 +954,31 @@ inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double switch(style) { case JKQTPArrow: - case JKQTPArrowAndStop: { + case JKQTPArrowAndBar: { 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)); + if (style==JKQTPArrowAndBar) painter.drawLine(QPointF(0,-tan__default_theta_open_tip*size), QPointF(0,tan__default_theta_open_tip*size)); painter.drawPolyline(poly, 3); } break; + case JKQTPHarpoonDecorator: + case JKQTPHarpoonDecoratorAndBar: { + painter.setPen(pinit); + if (style==JKQTPHarpoonDecoratorAndBar) painter.drawLine(QPointF(0,-tan__default_theta_open_tip*size), QPointF(0,tan__default_theta_open_tip*size)); + painter.drawLine(QPointF(0,0), QPointF(size, tan__default_theta_open_tip*size)); + } break; case JKQTPDoubleArrow: - case JKQTPDoubleArrowAndStop: { + case JKQTPDoubleArrowAndBar: { 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)); + if (style==JKQTPDoubleArrowAndBar) 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); @@ -968,16 +994,16 @@ inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double }; painter.drawPolygon(poly, 4); if (style==JKQTPFilledDoubleArrow) { - painter.translate(0.25*size, 0); + painter.translate(0.5*size, 0); painter.drawPolygon(poly, 4); - if (line_start) *line_start=QPointF(x,y)+QPointF(size*cos(angle_rad),size*sin(angle_rad)); + if (line_start) *line_start=QPointF(x,y)+QPointF(1.25*size*cos(angle_rad),1.25*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: { + case JKQTPTriangleDecoratorAndBar: { const QPointF poly[3] = { QPointF(size, -tan__default_theta_closed_tip*size), QPointF(0,0), @@ -986,12 +1012,12 @@ inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double 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 (style==JKQTPTriangleDecoratorAndBar) 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: { + case JKQTPFilledTriangleDecoratorAndBar: { const QPointF poly[3] = { QPointF(size, -tan__default_theta_closed_tip*size), QPointF(0,0), @@ -999,7 +1025,7 @@ inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double }; painter.setPen(p0); painter.drawConvexPolygon(poly, 3); - if (style==JKQTPFilledTriangleDecoratorAndStop) { + if (style==JKQTPFilledTriangleDecoratorAndBar) { painter.setPen(pinit); painter.drawLine(QPointF(0,-tan__default_theta_closed_tip*size), QPointF(0,tan__default_theta_closed_tip*size)); } @@ -1007,7 +1033,37 @@ inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double } break; + case JKQTPDiamondDecorator: + case JKQTPDiamondDecoratorAndBar: { + const QPointF poly[4] = { + QPointF(0,0), + QPointF(size/2.0, -tan__default_theta_closed_tip*size), + QPointF(size,0), + QPointF(size/2.0, tan__default_theta_closed_tip*size) + }; + painter.setBrush(Qt::NoBrush); + painter.setPen(pinit); + painter.drawConvexPolygon(poly, 4); + if (style==JKQTPDiamondDecoratorAndBar) 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 JKQTPFilledDiamondDecorator: + case JKQTPFilledDiamondDecoratorAndBar: { + const QPointF poly[4] = { + QPointF(0,0), + QPointF(size/2.0, -tan__default_theta_closed_tip*size), + QPointF(size,0), + QPointF(size/2.0, tan__default_theta_closed_tip*size) + }; + painter.setPen(p0); + painter.drawConvexPolygon(poly, 4); + if (style==JKQTPFilledDiamondDecoratorAndBar) { + 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: { @@ -1017,8 +1073,8 @@ inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double } 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)); + painter.drawEllipse(QRectF(0,-size/2.0,size,size)); + if (line_start) *line_start=QPointF(x,y)+QPointF(size*cos(angle_rad),size*sin(angle_rad)); } break; case JKQTPRectangleDecorator: @@ -1029,14 +1085,25 @@ inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double } 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)); + painter.drawRect(QRectF(0,-size/2.0,size,size)); + if (line_start) *line_start=QPointF(x,y)+QPointF(size*cos(angle_rad),size*sin(angle_rad)); } break; - case JKQTPVerticalDecorator: { + + case JKQTPBarDecorator: { painter.setPen(pinit); painter.drawLine(QPointF(0,-tan__default_theta_open_tip*size), QPointF(0,tan__default_theta_open_tip*size)); } break; + case JKQTPHalfBarDecorator: { + painter.setPen(pinit); + painter.drawLine(QPointF(0,0), QPointF(0,tan__default_theta_open_tip*size)); + } break; + + case JKQTPSkewedBarDecorator: { + painter.setPen(pinit); + painter.drawLine(QPointF(0.25*size,-tan__default_theta_open_tip*size), QPointF(-0.25*size,tan__default_theta_open_tip*size)); + } break; + case JKQTPBracketDecorator: { const QPointF poly[4] = { QPointF(-size*0.2,-tan__default_theta_open_tip*size), diff --git a/lib/jkqtplotter/graphs/jkqtpgeometric.cpp b/lib/jkqtplotter/graphs/jkqtpgeometric.cpp index 81ebc98216..fa1749613c 100644 --- a/lib/jkqtplotter/graphs/jkqtpgeometric.cpp +++ b/lib/jkqtplotter/graphs/jkqtpgeometric.cpp @@ -253,7 +253,7 @@ QColor JKQTPGeoText::getKeyLabelColor() const { JKQTPGeoLine::JKQTPGeoLine(JKQTBasePlotter* parent, double x1, double y1, double x2, double y2, QColor color, double lineWidth, Qt::PenStyle style): - JKQTPGeoBaseLine(color, lineWidth, style, parent) + JKQTPGeoBaseDecoratedLine(color, lineWidth, JKQTPNoDecorator, JKQTPNoDecorator, style, parent) { this->x1=x1; this->y1=y1; @@ -267,12 +267,14 @@ JKQTPGeoLine::JKQTPGeoLine(JKQTPlotter* parent, double x1, double y1, double x2, } JKQTPGeoLine::JKQTPGeoLine(JKQTBasePlotter *parent, double x1, double y1, double x2, double y2): - JKQTPGeoBaseLine(parent) + JKQTPGeoBaseDecoratedLine(parent) { this->x1=x1; this->y1=y1; this->x2=x2; this->y2=y2; + setHeadDecoratorStyle(JKQTPNoDecorator); + setTailDecoratorStyle(JKQTPNoDecorator); } JKQTPGeoLine::JKQTPGeoLine(JKQTPlotter *parent, double x1, double y1, double x2, double y2): @@ -305,13 +307,20 @@ void JKQTPGeoLine::draw(JKQTPEnhancedPainter& painter) { reserveHitTestData(2); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.setPen(getLinePen(painter, parent)); - QLineF l(QPointF(transformX(x1), transformY(y1)), QPointF(transformX(x2), transformY(y2))); - if (l.length()>0) { - painter.drawLine(l); + 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(), calcTailDecoratorSize(getLinePen(painter, getParent()).widthF()), &lx1); + JKQTPPlotLineDecorator(painter, xx2.x(), xx2.y(), angle2, getHeadDecoratorStyle(), calcHeadDecoratorSize(getLinePen(painter, getParent()).widthF()), &lx2); + // draw corrected line + painter.drawLine(QLineF(lx1, lx2)); addHitTestData(x1, y1); addHitTestData(x2, y2); } - } void JKQTPGeoLine::setX1(double __value) @@ -362,12 +371,10 @@ 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) + JKQTPGeoLine(parent, x1,y1,x2,y2,color, lineWidth, style) { - this->x1=x1; - this->y1=y1; - this->x2=x2; - this->y2=y2; + setHeadDecoratorStyle(headStyle); + setTailDecoratorStyle(tailStyle); } JKQTPGeoArrow::JKQTPGeoArrow(JKQTPlotter* parent, double x1, double y1, double x2, double y2, QColor color, JKQTPLineDecoratorStyle headStyle, JKQTPLineDecoratorStyle tailStyle, double lineWidth, Qt::PenStyle style): @@ -376,94 +383,10 @@ JKQTPGeoArrow::JKQTPGeoArrow(JKQTPlotter* parent, double x1, double y1, double x } -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) + JKQTPGeoBaseDecoratedHeadLine(color, lineWidth, JKQTPNoDecorator, style, parent) { this->x=x; this->y=y; @@ -621,8 +544,16 @@ void JKQTPGeoInfiniteLine::draw(JKQTPEnhancedPainter& painter) { QString(", \\ensuremath{\\mathrm{\\mathbf{d}}y/\\mathrm{\\mathbf{d}}x\\;=\\;%1/%2\\;=\\;%3\\;=\\;%4\\degree}").arg(jkqtp_floattolatexqstr(dy, 3)).arg(jkqtp_floattolatexqstr(dx, 3)).arg(jkqtp_floattolatexqstr(dy/dx, 3)).arg(jkqtp_floattolatexqstr(atan2(dy,dx), 1))); addHitTestData(x1, y1); addHitTestData(x2, y2); - } + if (two_sided==false && x>=xmin && x<=xmax && y>=ymin && y<=ymax) { + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.setPen(getLinePen(painter, parent)); + painter.setBrush(getLineColor()); + QPointF xx1(transformX(x),transformY(y)); + const double angle1=atan2(l.dy(), l.dx()); + JKQTPPlotLineDecorator(painter, xx1.x(), xx1.y(), angle1, getHeadDecoratorStyle(), calcHeadDecoratorSize(getLinePen(painter, getParent()).widthF())); + } + } } @@ -682,23 +613,24 @@ bool JKQTPGeoInfiniteLine::getTwoSided() const JKQTPGeoPolyLines::JKQTPGeoPolyLines(JKQTBasePlotter* parent, const QVector& points, QColor color, double lineWidth, Qt::PenStyle style): - JKQTPGeoBaseLine(color, lineWidth, style, parent) + JKQTPGeoBaseDecoratedLine(color, lineWidth, JKQTPNoDecorator, JKQTPNoDecorator, style, parent) { this->points=points; } + JKQTPGeoPolyLines::JKQTPGeoPolyLines(JKQTPlotter* parent, const QVector& points, QColor color, double lineWidth, Qt::PenStyle style): - JKQTPGeoBaseLine(color, lineWidth, style, parent) + JKQTPGeoPolyLines(parent->getPlotter(), points, color, lineWidth, style) { - this->points=points; } + JKQTPGeoPolyLines::JKQTPGeoPolyLines(JKQTBasePlotter *parent, QColor color, double lineWidth, Qt::PenStyle style): - JKQTPGeoBaseLine(color, lineWidth, style, parent) + JKQTPGeoBaseDecoratedLine(color, lineWidth, JKQTPNoDecorator, JKQTPNoDecorator, style, parent) { } JKQTPGeoPolyLines::JKQTPGeoPolyLines(JKQTPlotter *parent, QColor color, double lineWidth, Qt::PenStyle style): - JKQTPGeoBaseLine(color, lineWidth, style, parent) + JKQTPGeoPolyLines(parent->getPlotter(), color, lineWidth, style) { } @@ -745,16 +677,31 @@ bool JKQTPGeoPolyLines::getYMinMax(double& miny, double& maxy, double& smallestG void JKQTPGeoPolyLines::draw(JKQTPEnhancedPainter& painter) { clearHitTestData(); - reserveHitTestData(points.size()); + if (points.size()>=2) { + reserveHitTestData(points.size()); + + QVector path=transform(points); + painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); + painter.setPen(getLinePen(painter, parent)); + painter.setBrush(getLineColor()); + + // potentially draw line-end decorators/arrows + const double angle1=atan2(path[1].y()-path[0].y(), path[1].x()-path[0].x()); + const double angle2=atan2(path[path.size()-2].y()-path[path.size()-1].y(), path[path.size()-2].x()-path[path.size()-1].x()); + QPointF xx1=path[0], xx2=path[path.size()-1]; + QPointF lx1=xx1, lx2=xx2; + JKQTPPlotLineDecorator(painter, xx1.x(), xx1.y(), angle1, getTailDecoratorStyle(), calcTailDecoratorSize(getLinePen(painter, getParent()).widthF()), &lx1); + JKQTPPlotLineDecorator(painter, xx2.x(), xx2.y(), angle2, getHeadDecoratorStyle(), calcHeadDecoratorSize(getLinePen(painter, getParent()).widthF()), &lx2); + path[0]=lx1; + path[path.size()-1]=lx2; + + // draw corrected line + painter.drawPolyline(path.data(), path.size()); + for (const auto& p:points) { + addHitTestData(p.x(), p.y()); + } - QPainterPath path=transformToLinePath(points); - painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); - painter.setPen(getLinePen(painter, parent)); - painter.drawPath(path); - for (const auto& p:points) { - addHitTestData(p.x(), p.y()); } - } void JKQTPGeoPolyLines::setPoints(const QVector &__value) @@ -1478,6 +1425,60 @@ QColor JKQTPGeoSymbol::getKeyLabelColor() const return getSymbolColor(); } +JKQTPGeoBaseDecoratedHeadLine::JKQTPGeoBaseDecoratedHeadLine(QColor color, double lineWidth, JKQTPLineDecoratorStyle headStyle, Qt::PenStyle style, JKQTBasePlotter *parent): + JKQTPPlotObject(parent) +{ + setLineColor(color); + setLineWidth(lineWidth); + setLineStyle(style); + setHeadDecoratorStyle(headStyle); +} + +JKQTPGeoBaseDecoratedHeadLine::JKQTPGeoBaseDecoratedHeadLine(QColor color, double lineWidth, JKQTPLineDecoratorStyle headStyle, Qt::PenStyle style, JKQTPlotter *parent): + JKQTPGeoBaseDecoratedHeadLine(color, lineWidth, headStyle, style, parent->getPlotter()) +{ + +} + +JKQTPGeoBaseDecoratedHeadLine::JKQTPGeoBaseDecoratedHeadLine(JKQTBasePlotter *parent): + JKQTPPlotObject(parent) +{ + +} + +JKQTPGeoBaseDecoratedHeadLine::JKQTPGeoBaseDecoratedHeadLine(JKQTPlotter *parent): + JKQTPPlotObject(parent->getPlotter()) +{ + +} + +void JKQTPGeoBaseDecoratedHeadLine::setAlpha(float alpha) +{ + auto color=getLineColor(); + color.setAlphaF(alpha); + setLineColor(color); +} + +void JKQTPGeoBaseDecoratedHeadLine::setColor(QColor c) +{ + setLineColor(c); +} + +void JKQTPGeoBaseDecoratedHeadLine::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 JKQTPGeoBaseDecoratedHeadLine::getKeyLabelColor() const +{ + return getLineColor(); +} + + + JKQTPGeoBaseDecoratedLine::JKQTPGeoBaseDecoratedLine(QColor color, double lineWidth, JKQTPLineDecoratorStyle headStyle, JKQTPLineDecoratorStyle tailStyle, Qt::PenStyle style, JKQTBasePlotter *parent): JKQTPPlotObject(parent) { diff --git a/lib/jkqtplotter/graphs/jkqtpgeometric.h b/lib/jkqtplotter/graphs/jkqtpgeometric.h index 9d9bb7ece3..88cd944f46 100644 --- a/lib/jkqtplotter/graphs/jkqtpgeometric.h +++ b/lib/jkqtplotter/graphs/jkqtpgeometric.h @@ -79,6 +79,64 @@ public: protected: }; + + + + +/*! \brief This JKQTPPlotObject is used as base class for geometric drawing + elements that consist of lines with one decorated end (i.e. no filling of any kind is done) + \ingroup jkqtplotter_geoplots + +*/ + class JKQTPLOTTER_LIB_EXPORT JKQTPGeoBaseDecoratedHeadLine: public JKQTPPlotObject, public JKQTPGraphDecoratedHeadLineStyleMixin { + Q_OBJECT +public: + /*! \brief class contructor + + \param color color of drawing + \param lineWidth lineWidth of drawing + \param headStyle style of the head decoration + \param style line style of drawing + \param parent the parent plotter object + */ + explicit JKQTPGeoBaseDecoratedHeadLine(QColor color, double lineWidth, JKQTPLineDecoratorStyle headStyle, 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 style line style of drawing + \param parent the parent plotter object + */ + explicit JKQTPGeoBaseDecoratedHeadLine(QColor color, double lineWidth, JKQTPLineDecoratorStyle headStyle, Qt::PenStyle style, JKQTPlotter* parent); + /*! \brief class contructor + + */ + explicit JKQTPGeoBaseDecoratedHeadLine(JKQTBasePlotter* parent); + /*! \brief class contructor + + */ + explicit JKQTPGeoBaseDecoratedHeadLine(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: + +}; + + + + /*! \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 @@ -95,7 +153,7 @@ public: \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 @@ -105,15 +163,11 @@ public: \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 - - */ + /*! \brief class contructor */ explicit JKQTPGeoBaseDecoratedLine(JKQTBasePlotter* parent); - /*! \brief class contructor - - */ + /*! \brief class contructor */ explicit JKQTPGeoBaseDecoratedLine(JKQTPlotter* parent); @@ -355,15 +409,30 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoText: public JKQTPPlotObject, public JKQTPG QPen getPen(JKQTPEnhancedPainter& painter); }; -/*! \brief This JKQTPPlotObject is used to draw a line +/*! \brief This JKQTPPlotObject is used to draw a line, optionally line-end decorations (aka arrows) are pssible, but switched off by default. \ingroup jkqtplotter_geoplots + \image html JKQTPGeoLine_HeadTail.png + + \image html plot_geoline.png - \see \ref JKQTPlotterGeometricGraphs + + You can also activate line-end decorators (aka arrows) for this poly-line, by using code like this: + \code + line->setHeadDecoratorStyle(JKQTPFilledDoubleArrow); + line->setTailDecoratorStyle(JKQTPCircleDecorator); + \endcode + + This results in arrows drawn at the start (aka x1/y1, =tail) and end (aka x2/y2, =head) of the line. + + + \note The convenience class JKQTPGeoArrow activates line-end decorations (aka arows) by default and allows to select them in the constructor. + + \see JKQTPGeoArrow, \ref JKQTPlotterGeometricGraphs and \ref JKQTPlotterGeometricArrows */ -class JKQTPLOTTER_LIB_EXPORT JKQTPGeoLine: public JKQTPGeoBaseLine { +class JKQTPLOTTER_LIB_EXPORT JKQTPGeoLine: public JKQTPGeoBaseDecoratedLine { Q_OBJECT public: /*! \brief class constructor @@ -451,15 +520,19 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoLine: public JKQTPGeoBaseLine { }; -/*! \brief This JKQTPPlotObject is used to draw a line with decorations (e.g. arrows) +/*! \brief This convenience specialisation of JKQTPGeoLine is used to draw a line with decorations (e.g. arrows) \ingroup jkqtplotter_geoplots + This class does not add any functionality on top of JKQTPGeoLine, just activates line-end markers by default! + + \image html JKQTPGeoLine_HeadTail.png + \image html plot_geoarrows.png - \see \ref JKQTPlotterGeometricGraphs + \see JKQTPLineDecoratorStyle, JKQTPGeoLine, \ref JKQTPlotterGeometricArrows and \ref JKQTPlotterGeometricGraphs */ -class JKQTPLOTTER_LIB_EXPORT JKQTPGeoArrow: public JKQTPGeoBaseDecoratedLine { +class JKQTPLOTTER_LIB_EXPORT JKQTPGeoArrow: public JKQTPGeoLine { Q_OBJECT public: /*! \brief class constructor @@ -489,43 +562,12 @@ public: */ 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 @@ -534,10 +576,12 @@ protected: \image html plot_geoinfiniteline.png - \see \ref JKQTPlotterGeometricGraphs + You can add a decorator to the head of the line (i.e. the given start point (x,y) ) iff this line is one-sided, i.e. two_sided \c ==false . + + \see \ref JKQTPlotterGeometricGraphs and \ref JKQTPlotterGeometricArrows */ -class JKQTPLOTTER_LIB_EXPORT JKQTPGeoInfiniteLine: public JKQTPGeoBaseLine { +class JKQTPLOTTER_LIB_EXPORT JKQTPGeoInfiniteLine: public JKQTPGeoBaseDecoratedHeadLine { Q_OBJECT public: /*! \brief class constructor @@ -614,10 +658,19 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGeoInfiniteLine: public JKQTPGeoBaseLine { \image html plot_geolines.png - \see \ref JKQTPlotterGeometricGraphs + You can also activate line-end decorators (aka arrows) for this poly-line, by using code like this: + \code + polyLine->setHeadDecoratorStyle(JKQTPFilledDoubleArrow); + polyLine->setTailDecoratorStyle(JKQTPCircleDecorator); + \endcode + + This results in arrows drawn at the start (=tail) and end (=head) of the poly-line: + \image html geo_arrow_polylines.png + + \see \ref JKQTPlotterGeometricGraphs and \ref JKQTPlotterGeometricArrows */ -class JKQTPLOTTER_LIB_EXPORT JKQTPGeoPolyLines: public JKQTPGeoBaseLine { +class JKQTPLOTTER_LIB_EXPORT JKQTPGeoPolyLines: public JKQTPGeoBaseDecoratedLine { Q_OBJECT public: /*! \brief class constructor diff --git a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp index efd944f8dc..dcd010480b 100644 --- a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp +++ b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.cpp @@ -456,7 +456,7 @@ JKQTPGraphDecoratedLineStyleMixin::JKQTPGraphDecoratedLineStyleMixin(): { m_headDecoratorStyle=JKQTPLineDecoratorStyle::JKQTPDefaultLineDecorator; m_tailDecoratorStyle=JKQTPLineDecoratorStyle::JKQTPNoDecorator; - m_tailDecoratorSizeFactor=m_headDecoratorSizeFactor=9.0; + m_tailDecoratorSizeFactor=m_headDecoratorSizeFactor=8.0; } void JKQTPGraphDecoratedLineStyleMixin::initDecoratedLineStyle(JKQTBasePlotter *parent, int &parentPlotStyle) @@ -508,3 +508,60 @@ double JKQTPGraphDecoratedLineStyleMixin::getTailDecoratorSizeFactor() const { return m_tailDecoratorSizeFactor; } + +double JKQTPGraphDecoratedLineStyleMixin::calcTailDecoratorSize(double line_width) const +{ + return JKQTPLineDecoratorStyleCalcDecoratorSize(line_width, m_tailDecoratorSizeFactor); +} + +double JKQTPGraphDecoratedLineStyleMixin::calcHeadDecoratorSize(double line_width) const +{ + return JKQTPLineDecoratorStyleCalcDecoratorSize(line_width, m_headDecoratorSizeFactor); +} + + + +JKQTPGraphDecoratedHeadLineStyleMixin::JKQTPGraphDecoratedHeadLineStyleMixin(): + JKQTPGraphLineStyleMixin() +{ + m_headDecoratorStyle=JKQTPLineDecoratorStyle::JKQTPDefaultLineDecorator; + m_headDecoratorSizeFactor=8.0; +} + +void JKQTPGraphDecoratedHeadLineStyleMixin::initDecoratedHeadLineStyle(JKQTBasePlotter *parent, int &parentPlotStyle) +{ + initLineStyle(parent, parentPlotStyle); +} + +JKQTPGraphDecoratedHeadLineStyleMixin::~JKQTPGraphDecoratedHeadLineStyleMixin() +{ + +} + +void JKQTPGraphDecoratedHeadLineStyleMixin::setHeadDecoratorStyle(const JKQTPLineDecoratorStyle &__value) +{ + m_headDecoratorStyle=__value; +} + +JKQTPLineDecoratorStyle JKQTPGraphDecoratedHeadLineStyleMixin::getHeadDecoratorStyle() const +{ + return m_headDecoratorStyle; +} + + +void JKQTPGraphDecoratedHeadLineStyleMixin::setHeadDecoratorSizeFactor(const double &__value) +{ + m_headDecoratorSizeFactor=__value; +} + +double JKQTPGraphDecoratedHeadLineStyleMixin::getHeadDecoratorSizeFactor() const +{ + return m_headDecoratorSizeFactor; +} + +double JKQTPGraphDecoratedHeadLineStyleMixin::calcHeadDecoratorSize(double line_width) const +{ + return JKQTPLineDecoratorStyleCalcDecoratorSize(line_width, m_headDecoratorSizeFactor); +} + + diff --git a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h index 1057e72e16..ca5a2394e5 100644 --- a/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h +++ b/lib/jkqtplotter/jkqtpgraphsbasestylingmixins.h @@ -145,6 +145,57 @@ 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 a decorator (i.e. an arrow) at their head. It extends JKQTPGraphLineStyleMixin + \ingroup jkqtplotter_basegraphs_stylemixins + + supported properties: + - head/ arrow style + . + + \see JKQTPGraphDecoratedLineStyleMixin for a Mix-In for both ends +*/ +class JKQTPLOTTER_LIB_EXPORT JKQTPGraphDecoratedHeadLineStyleMixin: public JKQTPGraphLineStyleMixin { + Q_GADGET +public: + /** \brief class constructor */ + JKQTPGraphDecoratedHeadLineStyleMixin(); + /** \brief initiaize the line style (from the parent plotter) */ + void initDecoratedHeadLineStyle(JKQTBasePlotter *parent, int &parentPlotStyle); + + virtual ~JKQTPGraphDecoratedHeadLineStyleMixin(); + + /** \brief set the head decorator style */ + void setHeadDecoratorStyle(const JKQTPLineDecoratorStyle & __value); + /** \brief get the head decorator style */ + JKQTPLineDecoratorStyle getHeadDecoratorStyle() const; + + /** \copydoc m_headDecoratorSizeFactor */ + void setHeadDecoratorSizeFactor(const double & __value); + /** \copydoc m_headDecoratorSizeFactor */ + double getHeadDecoratorSizeFactor() const; + + /** \brief calculates the tail decorator size from the line width \a line_width, using m_headDecoratorSizeFactor and a non-linear scaling function + * + * \see JKQTPLineDecoratorStyleCalcDecoratorSize() + */ + double calcHeadDecoratorSize(double line_width) const; + + + + Q_PROPERTY(JKQTPLineDecoratorStyle headDecoratorStyle MEMBER m_headDecoratorStyle READ getHeadDecoratorStyle WRITE setHeadDecoratorStyle) + Q_PROPERTY(double headDecoratorSizeFactor MEMBER m_headDecoratorSizeFactor READ getHeadDecoratorSizeFactor WRITE setHeadDecoratorSizeFactor) +private: + /** \brief head decorator style */ + JKQTPLineDecoratorStyle m_headDecoratorStyle; + /** \brief head decorator size-factor, used to calculate the size of the arrow from the line width */ + double m_headDecoratorSizeFactor; +}; + + + + + /*! \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 @@ -152,6 +203,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPGraphLineStyleMixin { supported properties: - head/tail arrow style . + + \see JKQTPGraphDecoratedHeadLineStyleMixin for a Mix-In for one end (head) only */ class JKQTPLOTTER_LIB_EXPORT JKQTPGraphDecoratedLineStyleMixin: public JKQTPGraphLineStyleMixin { Q_GADGET @@ -181,6 +234,17 @@ public: /** \copydoc m_tailDecoratorSizeFactor */ double getTailDecoratorSizeFactor() const; + /** \brief calculates the tail decorator size from the line width \a line_width, using m_tailDecoratorSizeFactor and a non-linear scaling function + * + * \see JKQTPLineDecoratorStyleCalcDecoratorSize() + */ + double calcTailDecoratorSize(double line_width) const; + /** \brief calculates the tail decorator size from the line width \a line_width, using m_headDecoratorSizeFactor and a non-linear scaling function + * + * \see JKQTPLineDecoratorStyleCalcDecoratorSize() + */ + double calcHeadDecoratorSize(double line_width) const; + Q_PROPERTY(JKQTPLineDecoratorStyle headDecoratorStyle MEMBER m_headDecoratorStyle READ getHeadDecoratorStyle WRITE setHeadDecoratorStyle) @@ -202,7 +266,6 @@ private: - /*! \brief This Mix-In class provides setter/getter methods, storage and other facilities for the graph symbols style \ingroup jkqtplotter_basegraphs_stylemixins diff --git a/screenshots/geo_arrows.png b/screenshots/geo_arrows.png new file mode 100644 index 0000000000..a0af9b5198 Binary files /dev/null and b/screenshots/geo_arrows.png differ diff --git a/screenshots/geo_arrows_small.png b/screenshots/geo_arrows_small.png new file mode 100644 index 0000000000..930bfcc731 Binary files /dev/null and b/screenshots/geo_arrows_small.png differ