diff --git a/doc/dox/examples_and_tutorials.dox b/doc/dox/examples_and_tutorials.dox
index 8f860e4c07..099a8fdb88 100644
--- a/doc/dox/examples_and_tutorials.dox
+++ b/doc/dox/examples_and_tutorials.dox
@@ -40,9 +40,12 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
\image html impulsesplot_small.png
| \subpage JKQTPlotterImpulsePlots
| `JKQTPImpulsesVerticalGraph` and `JKQTPImpulsesHorizontalGraph` C++-style QVector as plot data
diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox
index 7661e8505f..332e2b52b0 100644
--- a/doc/dox/whatsnew.dox
+++ b/doc/dox/whatsnew.dox
@@ -48,6 +48,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
NEW: added property drawLineInForeground to JKQTPXYLineGraph and JKQTPXYParametrizedScatterGraph
NEW: added JKQTPXYGraph::setKeyColumn()/JKQTPXYGraph::getKeyColumn() and JKQTPXYGraph::setValueColumn()/JKQTPXYGraph::getValueColumn() and corresponding functions in other classes. In most graph classes they point to xColumn for key and yColumn for values. These functions are virtual and overwritten in derived classes with horizontally oriented graphs, where they point to yColumn for key and yColumn for value. This way you can write generic code with classes for both orientations.
NEW: barcharts (derived from JKQTPBarGraphBase) can be configured to use different fill styles above and below the baseline, see JKQTPBarGraphBase::FillMode
+ NEW: added new error indicator styles JKQTPErrorHalfBarsOutwards, JKQTPErrorHalfBarsInwards, JKQTPErrorHalfBarsAbove, JKQTPErrorHalfBarsBelow which are especially useful for barcharts
JKQTMathText:
diff --git a/doc/images/JKQTPBarHorizontalErrorGraph.png b/doc/images/JKQTPBarHorizontalErrorGraph.png
new file mode 100644
index 0000000000..f86c5c14f3
Binary files /dev/null and b/doc/images/JKQTPBarHorizontalErrorGraph.png differ
diff --git a/doc/images/JKQTPBarHorizontalErrorGraph_small.png b/doc/images/JKQTPBarHorizontalErrorGraph_small.png
new file mode 100644
index 0000000000..4fca80d475
Binary files /dev/null and b/doc/images/JKQTPBarHorizontalErrorGraph_small.png differ
diff --git a/doc/images/JKQTPBarVerticalErrorGraph.png b/doc/images/JKQTPBarVerticalErrorGraph.png
new file mode 100644
index 0000000000..c8646e9e0f
Binary files /dev/null and b/doc/images/JKQTPBarVerticalErrorGraph.png differ
diff --git a/doc/images/JKQTPBarVerticalErrorGraph_small.png b/doc/images/JKQTPBarVerticalErrorGraph_small.png
new file mode 100644
index 0000000000..17c9385ace
Binary files /dev/null and b/doc/images/JKQTPBarVerticalErrorGraph_small.png differ
diff --git a/doc/images/plot_bargraphhorploterr.png b/doc/images/plot_bargraphhorploterr.png
deleted file mode 100644
index 7bcd1236ae..0000000000
Binary files a/doc/images/plot_bargraphhorploterr.png and /dev/null differ
diff --git a/doc/images/plot_bargraphverploterr.png b/doc/images/plot_bargraphverploterr.png
deleted file mode 100644
index 21bbe73ee6..0000000000
Binary files a/doc/images/plot_bargraphverploterr.png and /dev/null differ
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 8f738627ce..1ed9c6b6ac 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -48,6 +48,7 @@ add_subdirectory(jkqtplot_test)
add_subdirectory(advplotstyling)
add_subdirectory(barchart)
add_subdirectory(boxplot)
+add_subdirectory(barchart_errorbars)
add_subdirectory(barchart_twocolor)
add_subdirectory(contourplot)
add_subdirectory(datastore)
@@ -61,6 +62,7 @@ add_subdirectory(distributionplot)
add_subdirectory(errorbarstyles)
add_subdirectory(evalcurve)
add_subdirectory(filledgraphs)
+add_subdirectory(filledgraphs_errors)
add_subdirectory(functionplot)
add_subdirectory(geo_arrows)
add_subdirectory(geo_simple)
diff --git a/examples/barchart_errorbars/CMakeLists.txt b/examples/barchart_errorbars/CMakeLists.txt
new file mode 100644
index 0000000000..4a1e90f78d
--- /dev/null
+++ b/examples/barchart_errorbars/CMakeLists.txt
@@ -0,0 +1,34 @@
+cmake_minimum_required(VERSION 3.16)
+
+set(EXAMPLE_NAME barchart_errorbars)
+set(EXENAME jkqtptest_${EXAMPLE_NAME})
+
+message( STATUS ".. Building Example ${EXAMPLE_NAME}" )
+
+
+# Set up source files
+set(SOURCES barchart_errorbars.cpp )
+set(HEADERS )
+set(RESOURCES )
+set(UIS )
+
+add_executable(${EXENAME} WIN32 ${SOURCES} ${HEADERS} ${RESOURCES} ${UIS})
+target_link_libraries(${EXENAME} JKQTPExampleToolsLib)
+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()
+
+# precomiled headers to speed up compilation
+if (JKQtPlotter_BUILD_WITH_PRECOMPILED_HEADERS)
+ target_precompile_headers(${EXENAME} REUSE_FROM jkqtptest_simpletest)
+endif (JKQtPlotter_BUILD_WITH_PRECOMPILED_HEADERS)
+
+
+# Installation
+install(TARGETS ${EXENAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+#Installation of Qt DLLs on Windows
+jkqtplotter_deployqt(${EXENAME})
diff --git a/examples/barchart_errorbars/README.md b/examples/barchart_errorbars/README.md
new file mode 100644
index 0000000000..ec29c18f51
--- /dev/null
+++ b/examples/barchart_errorbars/README.md
@@ -0,0 +1,62 @@
+# Example (JKQTPlotter): Barchart With Error Bars {#JKQTPlotterBarchartsErrorBars}
+This project (see [`barchart_errorbars`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/barchart_errorbars) shows how to draw barcharts with different styles of error indicators.
+
+The source code of the main application is (see [`barchart_errorbars.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/barchart_errorbars/barchart_errorbars.cpp):
+```.cpp
+ // 1. create a plotter window and get a pointer to the internal datastore (for convenience)
+ JKQTPDatastore* ds=plot.getDatastore();
+
+ // 2. now we create three columns for key and value
+ size_t columnK=ds->addLinearColumn(6, 0.4*JKQTPSTATISTICS_PI, 2.2*JKQTPSTATISTICS_PI,"k");
+ size_t columnV=ds->addColumnCalculatedFromColumn(columnK, &cos, "v");
+ size_t columnE=ds->addColumnCalculatedFromColumn(columnK, [](double x) { return 0.05+0.06*(1.0+sin(x)); }, "error");
+
+ // 3. create a graph in the plot, which plots the dataset with symmetric:
+ JKQTPBarVerticalErrorGraph* graph1=new JKQTPBarVerticalErrorGraph(&plot);
+ graph1->setKeyColumn(columnK);
+ graph1->setValueColumn(columnV);
+ graph1->setBarErrorColumn(columnE);
+ // set error indicator style
+ graph1->setBarErrorStyle(JKQTPErrorBars);
+ graph1->setTitle(QObject::tr("JKQTPErrorBars"));
+ plot.addGraph(graph1);
+
+ // 4. create a second graph in the plot, which plots the second dataset with outer error bars only:
+ JKQTPBarVerticalErrorGraph* graph2=new JKQTPBarVerticalErrorGraph(&plot);
+ graph2->setKeyColumn(columnK);
+ graph2->setValueColumn(columnV);
+ graph2->setBarErrorColumn(columnE);
+ // set error indicator style
+ graph2->setBarErrorStyle(JKQTPErrorHalfBarsOutwards);
+ graph2->setTitle(QObject::tr("JKQTPErrorHalfBarsOutwards"));
+ plot.addGraph(graph2);
+
+ // 5. now we set the graphs, so they are plotted side-by-side
+ // This function searches all JKQTPBarHorizontalGraph in the current
+ // plot and sets their shift/scale so they form a nice plot with
+ // side-by-side groups
+ graph1->autoscaleBarWidthAndShift(0.9, 0.9);
+
+
+ // 6 autoscale the plot so the graph is contained
+ plot.zoomToFit();
+
+ // 7. show plotter and make it a decent size
+ plot.getPlotter()->setKeyPosition(JKQTPKeyInsideTopLeft);
+ plot.setWindowTitle(title);
+ plot.show();
+ plot.resize(400,400);
+```
+
+
+The result looks like this:
+
+![barchart_errorbars](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/barchart_errorbars.png)
+
+
+
+In order to draw horizontal error bars, you have to use `JKQTPBarHorizontalErrorGraph` instead of `JKQTPBarVerticalErrorGraph`:
+
+![barchart_errorbars_hor](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/barchart_errorbars_hor.png)
+
+
diff --git a/examples/barchart_errorbars/barchart_errorbars.cpp b/examples/barchart_errorbars/barchart_errorbars.cpp
new file mode 100644
index 0000000000..35f5e85b35
--- /dev/null
+++ b/examples/barchart_errorbars/barchart_errorbars.cpp
@@ -0,0 +1,77 @@
+/** \example barchart_errorbars.cpp
+ * Shows how to draw Barcharts with errorbars in a JKQTPlotter
+ *
+ * \ref JKQTPlotterBarchartsErrorBars
+ */
+
+#include "jkqtpexampleapplication.h"
+#include
+#include "jkqtplotter/jkqtplotter.h"
+#include "jkqtplotter/graphs/jkqtpscatter.h"
+#include "jkqtplotter/graphs/jkqtpbarchart.h"
+#include "jkqtpexampleapplication.h"
+#include "jkqtcommon/jkqtpmathtools.h"
+
+
+
+template
+void doExample(JKQTPlotter& plot, const QString& title)
+{
+ // 1. create a plotter window and get a pointer to the internal datastore (for convenience)
+ JKQTPDatastore* ds=plot.getDatastore();
+
+ // 2. now we create three columns for key and value
+ size_t columnK=ds->addLinearColumn(6, 0.4*JKQTPSTATISTICS_PI, 2.2*JKQTPSTATISTICS_PI,"k");
+ size_t columnV=ds->addColumnCalculatedFromColumn(columnK, &cos, "v");
+ size_t columnE=ds->addColumnCalculatedFromColumn(columnK, [](double x) { return 0.05+0.06*(1.0+sin(x)); }, "error");
+
+ // 3. create a graph in the plot, which plots the dataset with symmetric:
+ TCHART* graph1=new TCHART(&plot);
+ graph1->setKeyColumn(columnK);
+ graph1->setValueColumn(columnV);
+ graph1->setBarErrorColumn(columnE);
+ // set error indicator style
+ graph1->setBarErrorStyle(JKQTPErrorBars);
+ graph1->setTitle(QObject::tr("JKQTPErrorBars"));
+ plot.addGraph(graph1);
+
+ // 4. create a second graph in the plot, which plots the second dataset with outer error bars only:
+ TCHART* graph2=new TCHART(&plot);
+ graph2->setKeyColumn(columnK);
+ graph2->setValueColumn(columnV);
+ graph2->setBarErrorColumn(columnE);
+ // set error indicator style
+ graph2->setBarErrorStyle(JKQTPErrorHalfBarsOutwards);
+ graph2->setTitle(QObject::tr("JKQTPErrorHalfBarsOutwards"));
+ plot.addGraph(graph2);
+
+ // 5. now we set the graphs, so they are plotted side-by-side
+ // This function searches all JKQTPBarHorizontalGraph in the current
+ // plot and sets their shift/scale so they form a nice plot with
+ // side-by-side groups
+ graph1->autoscaleBarWidthAndShift(0.9, 0.9);
+
+
+ // 6 autoscale the plot so the graph is contained
+ plot.zoomToFit();
+
+ // 7. show plotter and make it a decent size
+ plot.getPlotter()->setKeyPosition(JKQTPKeyInsideTopLeft);
+ plot.setWindowTitle(title);
+ plot.show();
+ plot.resize(400,400);
+}
+
+int main(int argc, char* argv[])
+{
+
+ JKQTPAppSettingController highDPIController(argc,argv);
+ JKQTPExampleApplication app(argc, argv);
+
+
+ JKQTPlotter plotV, plotH;
+ doExample(plotV, "1: JKQTPBarVerticalErrorGraph");
+ doExample(plotH, "2: JKQTPBarHorizontalErrorGraph");
+
+ return app.exec();
+}
diff --git a/lib/jkqtplotter/graphs/jkqtpbarchart.cpp b/lib/jkqtplotter/graphs/jkqtpbarchart.cpp
index a39704a038..3db4a4e4f8 100644
--- a/lib/jkqtplotter/graphs/jkqtpbarchart.cpp
+++ b/lib/jkqtplotter/graphs/jkqtpbarchart.cpp
@@ -363,12 +363,51 @@ bool JKQTPBarHorizontalErrorGraph::usesColumn(int c) const
bool JKQTPBarHorizontalErrorGraph::getXMinMax(double &minx, double &maxx, double &smallestGreaterZero)
{
if (xErrorColumn<0 || xErrorStyle==JKQTPNoError) {
- return JKQTPBarHorizontalGraph::getXMinMax(minx, maxx, smallestGreaterZero);
- } else {
- bool start=false;
minx=0;
maxx=0;
smallestGreaterZero=0;
+ if (getBaseline()>0) {
+ smallestGreaterZero=getBaseline();
+ minx=getBaseline();
+ maxx=getBaseline();
+ }
+
+ if (parent==nullptr) return false;
+
+ JKQTPDatastore* datastore=parent->getDatastore();
+ int imax=0;
+ int imin=0;
+ if (getIndexRange(imin, imax)) {
+
+
+ for (int i=imin; imaxx) maxx=yv;
+ if (yvget(static_cast(xColumn),static_cast(i));
+ if (JKQTPIsOKFloat(yv)) {
+ if (yv>maxx) maxx=yv;
+ if (yv0) {
+ smallestGreaterZero=getBaseline();
+ minx=getBaseline();
+ maxx=getBaseline();
+ }
if (parent==nullptr) return false;
@@ -377,25 +416,25 @@ bool JKQTPBarHorizontalErrorGraph::getXMinMax(double &minx, double &maxx, double
int imin=0;
if (getIndexRange(imin, imax)) {
+
for (int i=imin; iget(static_cast(xColumn),static_cast(i))+getXErrorU(i, datastore);
- const double xvv=datastore->get(static_cast(xColumn),static_cast(i))-getXErrorL(i, datastore);
- if (JKQTPIsOKFloat(xv) && JKQTPIsOKFloat(xvv) ) {
- if (start || xv>maxx) maxx=xv;
- if (start || xvmaxx) maxx=xvv;
- if (xvvget(static_cast(xColumn),static_cast(i))+getXErrorU(i, datastore);
+ const double yvv=datastore->get(static_cast(xColumn),static_cast(i))-getXErrorL(i, datastore);
+ if (JKQTPIsOKFloat(yv) && JKQTPIsOKFloat(yvv) ) {
+ if (start || yv>maxx) maxx=yv;
+ if (start || yvmaxx) maxx=yvv;
+ if (start || yvv=0 || xErrorColumnLower>=0) && (xErrorStyle==JKQTPErrorBars || xErrorStyle==JKQTPErrorBarsLines|| xErrorStyle==JKQTPErrorBarsPolygons
- || xErrorStyle==JKQTPErrorSimpleBars || xErrorStyle==JKQTPErrorSimpleBarsLines|| xErrorStyle==JKQTPErrorSimpleBarsPolygons)) {
+ if ((xErrorColumn>=0 || xErrorColumnLower>=0)
+ && (xErrorStyle==JKQTPErrorBars || xErrorStyle==JKQTPErrorBarsLines|| xErrorStyle==JKQTPErrorBarsPolygons
+ || xErrorStyle==JKQTPErrorSimpleBars || xErrorStyle==JKQTPErrorSimpleBarsLines|| xErrorStyle==JKQTPErrorSimpleBarsPolygons))
+ {
double x0=parentGraph->transformX(xv+xrelshift*deltax-xl); bool x0ok=JKQTPIsOKFloat(x0);
double x1=parentGraph->transformX(xv+xrelshift*deltax+xe); bool x1ok=JKQTPIsOKFloat(x1);
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
@@ -427,10 +429,79 @@ void JKQTPGraphErrorStyleMixin::intPlotXYErrorIndicators(JKQTPEnhancedPainter& p
l=JKQTPClipLine(l, cliprect);
if (l.length()>0) painter.drawLine(l);
}
+ }
+ // y-errorbars
+ if ((yErrorColumn>=0 || yErrorColumnLower>=0)
+ && (yErrorStyle==JKQTPErrorBars || yErrorStyle==JKQTPErrorBarsLines || yErrorStyle==JKQTPErrorBarsPolygons
+ || yErrorStyle==JKQTPErrorSimpleBars || yErrorStyle==JKQTPErrorSimpleBarsLines || yErrorStyle==JKQTPErrorSimpleBarsPolygons))
+ {
+ double y0=parentGraph->transformY(yv+yrelshift*deltay-yl); bool y0ok=JKQTPIsOKFloat(y0);
+ double y1=parentGraph->transformY(yv+yrelshift*deltay+ye); bool y1ok=JKQTPIsOKFloat(y1);
+ painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
+ QPen pp=p;
+ if (!defaultErrorColor) pp.setColor(terrCol);
+ painter.setPen(pp);
+ QList elines;
+ if (y0ok&&y1ok&&xok&&yok) {
+ elines<transformY(parent->getYMin()));
+ else elines<transformY(parent->getYMax())); // inverted axis!
+ } else if (!y0ok&&y1ok&&xok&&yok) {
+ elines<transformY(parent->getYMax()));
+ else elines<transformY(parent->getYMin()));
}
- // y-errorbars
- if ((yErrorColumn>=0 || yErrorColumnLower>=0) && (yErrorStyle==JKQTPErrorBars || yErrorStyle==JKQTPErrorBarsLines || yErrorStyle==JKQTPErrorBarsPolygons
- || yErrorStyle==JKQTPErrorSimpleBars || yErrorStyle==JKQTPErrorSimpleBarsLines || yErrorStyle==JKQTPErrorSimpleBarsPolygons)) {
+ for (QLineF& l: elines) {
+ l=JKQTPClipLine(l, cliprect);
+ if (l.length()>0) painter.drawLine(l);
+ }
+ }
+
+ // half errorbars
+ if ((xErrorColumn>=0) && (xErrorStyle==JKQTPErrorHalfBarsAbove|| xErrorStyle==JKQTPErrorHalfBarsInwards|| xErrorStyle==JKQTPErrorHalfBarsBelow|| xErrorStyle==JKQTPErrorHalfBarsOutwards))
+ {
+ double x0=parentGraph->transformX(xv+xrelshift*deltax-xl); bool x0ok=JKQTPIsOKFloat(x0);
+ double x1=parentGraph->transformX(xv+xrelshift*deltax+xe); bool x1ok=JKQTPIsOKFloat(x1);
+ painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
+ QPen pp=p;
+ if (!defaultErrorColor) pp.setColor(terrCol);
+ painter.setPen(pp);
+ QList elines;
+ if ( (xErrorStyle==JKQTPErrorHalfBarsAbove
+ || (xErrorStyle==JKQTPErrorHalfBarsOutwards && xv>0.0)
+ || (xErrorStyle==JKQTPErrorHalfBarsInwards && xv<0.0))
+ &&x1ok&&xok&&yok) {
+ elines<=0.0))
+ &&x0ok&&xok&&yok) {
+ elines<0) painter.drawLine(l);
+ }
+ }
+
+
+ // half errorbars
+ if ((yErrorColumn>=0) && (yErrorStyle==JKQTPErrorHalfBarsAbove|| yErrorStyle==JKQTPErrorHalfBarsInwards|| yErrorStyle==JKQTPErrorHalfBarsBelow|| yErrorStyle==JKQTPErrorHalfBarsOutwards))
+ {
double y0=parentGraph->transformY(yv+yrelshift*deltay-yl); bool y0ok=JKQTPIsOKFloat(y0);
double y1=parentGraph->transformY(yv+yrelshift*deltay+ye); bool y1ok=JKQTPIsOKFloat(y1);
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
@@ -438,56 +509,48 @@ void JKQTPGraphErrorStyleMixin::intPlotXYErrorIndicators(JKQTPEnhancedPainter& p
if (!defaultErrorColor) pp.setColor(terrCol);
painter.setPen(pp);
QList elines;
- if (y0ok&&y1ok&&xok&&yok) {
- elines<0.0)
+ || (yErrorStyle==JKQTPErrorHalfBarsInwards && yv<0.0))
+ &&yok&&y1ok&&xok) {
+ elines<=0.0))
+ &&y0ok&&yok&&xok) {
elines<transformY(parent->getYMin()));
- else elines<transformY(parent->getYMax())); // inverted axis!
- } else if (!y0ok&&y1ok&&xok&&yok) {
- elines<transformY(parent->getYMax()));
- else elines<transformY(parent->getYMin()));
+ elines<0) painter.drawLine(l);
}
+ }
+
+
+ // error boxes
+ if (yErrorStyle==JKQTPErrorBoxes || xErrorStyle==JKQTPErrorBoxes || yErrorStyle==JKQTPErrorEllipses || xErrorStyle==JKQTPErrorEllipses ) {
+ double y0=parentGraph->transformY(yv+yrelshift*deltay-yl); bool y0ok=JKQTPIsOKFloat(y0);
+ double y1=parentGraph->transformY(yv+yrelshift*deltay+ye); bool y1ok=JKQTPIsOKFloat(y1);
+ double x0=parentGraph->transformX(xv+xrelshift*deltax-xl); bool x0ok=JKQTPIsOKFloat(x0);
+ double x1=parentGraph->transformX(xv+xrelshift*deltax+xe); bool x1ok=JKQTPIsOKFloat(x1);
+ painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
+ QPen pp=p;
+ if (!defaultErrorColor) pp.setColor(terrCol);
+ painter.setPen(pp);
+ QBrush bb=b;
+ if (!defaultErrorColor) bb.setColor(terrFillCol);
+ painter.setBrush(bb);
+
+ const QRectF errRect=QRectF(QPointF(x0,y0), QPointF(x1,y1));
+ if (((y0ok&&y1ok)||(x0ok&&x1ok))&&cliprect.intersects(errRect)) {
+ if (yErrorStyle==JKQTPErrorEllipses || xErrorStyle==JKQTPErrorEllipses) painter.drawEllipse(errRect);
+ else painter.drawRect(errRect);
}
- // error boxes
- if (yErrorStyle==JKQTPErrorBoxes || xErrorStyle==JKQTPErrorBoxes || yErrorStyle==JKQTPErrorEllipses || xErrorStyle==JKQTPErrorEllipses ) {
- double y0=parentGraph->transformY(yv+yrelshift*deltay-yl); bool y0ok=JKQTPIsOKFloat(y0);
- double y1=parentGraph->transformY(yv+yrelshift*deltay+ye); bool y1ok=JKQTPIsOKFloat(y1);
- double x0=parentGraph->transformX(xv+xrelshift*deltax-xl); bool x0ok=JKQTPIsOKFloat(x0);
- double x1=parentGraph->transformX(xv+xrelshift*deltax+xe); bool x1ok=JKQTPIsOKFloat(x1);
- painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
- QPen pp=p;
- if (!defaultErrorColor) pp.setColor(terrCol);
- painter.setPen(pp);
- QBrush bb=b;
- if (!defaultErrorColor) bb.setColor(terrFillCol);
- painter.setBrush(bb);
-
- const QRectF errRect=QRectF(QPointF(x0,y0), QPointF(x1,y1));
- if (((y0ok&&y1ok)||(x0ok&&x1ok))&&cliprect.intersects(errRect)) {
- if (yErrorStyle==JKQTPErrorEllipses || xErrorStyle==JKQTPErrorEllipses) painter.drawEllipse(errRect);
- else painter.drawRect(errRect);
- }
-
-
- } //}
+ }
// x-errorlines
if (pastFirst && (xErrorStyle==JKQTPErrorLines || xErrorStyle==JKQTPErrorBarsLines || xErrorStyle==JKQTPErrorSimpleBarsLines)) {
double xl1m=xmold;
diff --git a/lib/jkqtplotter/jkqtptools.cpp b/lib/jkqtplotter/jkqtptools.cpp
index 9b577e64f7..d67f9cf879 100644
--- a/lib/jkqtplotter/jkqtptools.cpp
+++ b/lib/jkqtplotter/jkqtptools.cpp
@@ -197,6 +197,10 @@ QString JKQTPErrorPlotstyle2String(JKQTPErrorPlotstyle pos) {
case JKQTPErrorEllipses: return "error_ell";
case JKQTPErrorLines: return "error_lines";
case JKQTPErrorBars: return "error_bars";
+ case JKQTPErrorHalfBarsAbove: return "error_bars_half_above";
+ case JKQTPErrorHalfBarsBelow: return "error_bars_half_below";
+ case JKQTPErrorHalfBarsInwards: return "error_bars_half_inwards";
+ case JKQTPErrorHalfBarsOutwards: return "error_bars_half_outwards";
case JKQTPErrorSimpleBars: return "error_simplebars";
case JKQTPErrorPolygons: return "error_polygons";
case JKQTPErrorBarsLines: return "error_bars_lines";
@@ -220,6 +224,10 @@ JKQTPErrorPlotstyle String2JKQTPErrorPlotstyle(const QString& pos) {
if (s=="error_bars_polygons") return JKQTPErrorBarsPolygons;
if (s=="error_simplebars_lines") return JKQTPErrorSimpleBarsLines;
if (s=="error_simplebars_polygons") return JKQTPErrorSimpleBarsPolygons;
+ if (s=="error_bars_half_above") return JKQTPErrorHalfBarsAbove;
+ if (s=="error_bars_half_below") return JKQTPErrorHalfBarsBelow;
+ if (s=="error_bars_half_inwards") return JKQTPErrorHalfBarsInwards;
+ if (s=="error_bars_half_outwards") return JKQTPErrorHalfBarsOutwards;
return JKQTPNoError;
}
diff --git a/lib/jkqtplotter/jkqtptools.h b/lib/jkqtplotter/jkqtptools.h
index 78a24f6033..6a275f3b06 100644
--- a/lib/jkqtplotter/jkqtptools.h
+++ b/lib/jkqtplotter/jkqtptools.h
@@ -582,6 +582,10 @@ enum JKQTPErrorPlotstyle {
JKQTPErrorSimpleBars=6, /*!< \brief simplified error bars for each data point \image html JKQTPErrorSimpleBars.png */
JKQTPErrorLines=5, /*!< \brief a second and third graph line above and below the actual data which indicates the error value \image html JKQTPErrorLines.png */
JKQTPErrorBars=4, /*!< \brief error bars for each data point \image html JKQTPErrorBars.png */
+ JKQTPErrorHalfBarsOutwards=11, /*!< \brief half error bars for each data point, pointing outwards \image html JKQTPErrorHalfBarsOutwards.png */
+ JKQTPErrorHalfBarsInwards=12, /*!< \brief half error bars for each data point, pointing inwards \image html JKQTPErrorHalfBarsInwards.png */
+ JKQTPErrorHalfBarsAbove=13, /*!< \brief half error bars for each data point, pointing up \image html JKQTPErrorHalfBarsAbove.png */
+ JKQTPErrorHalfBarsBelow=14, /*!< \brief half error bars for each data point, pointing down \image html JKQTPErrorHalfBarsBelow.png */
JKQTPErrorPolygons=3, /*!< \brief line error lines, but with filled range in between \image html JKQTPErrorPolygons.png */
JKQTPErrorBarsLines=2, /*!< \brief error bars and lines for each data point \image html JKQTPErrorBarsLines.png */
JKQTPErrorBarsPolygons=1, /*!< \brief error bars and polygons for each data point \image html JKQTPErrorBarsPolygons.png */
diff --git a/screenshots/barchart_errorbars.png b/screenshots/barchart_errorbars.png
new file mode 100644
index 0000000000..3902172001
Binary files /dev/null and b/screenshots/barchart_errorbars.png differ
diff --git a/screenshots/barchart_errorbars_hor.png b/screenshots/barchart_errorbars_hor.png
new file mode 100644
index 0000000000..c4c98310a6
Binary files /dev/null and b/screenshots/barchart_errorbars_hor.png differ
diff --git a/screenshots/barchart_errorbars_hor_small.png b/screenshots/barchart_errorbars_hor_small.png
new file mode 100644
index 0000000000..4fca80d475
Binary files /dev/null and b/screenshots/barchart_errorbars_hor_small.png differ
diff --git a/screenshots/barchart_errorbars_small.png b/screenshots/barchart_errorbars_small.png
new file mode 100644
index 0000000000..17c9385ace
Binary files /dev/null and b/screenshots/barchart_errorbars_small.png differ
|