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