diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 1edd04e4bd..c2984058a1 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -125,6 +125,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
scatter_customsymbol
simpletest
barchart/barchart,barchart_hor
+ barchart_twocolor/barchart_twocolor,barchart_twocolor_hor
wiggleplots/wiggleplot_x,wiggleplot_y
advplotstyling/advancedlineandfillstyling
boxplot
@@ -172,6 +173,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
scatter/JKQTPXYScatterGraph,JKQTPXYScatterErrorGraph/--smallscreenshotplot
simpletest/JKQTPXYLineGraph/--smallscreenshotplot
barchart/JKQTPBarVerticalGraph,JKQTPBarHorizontalGraph/--smallscreenshotplot
+ barchart_twocolor/JKQTPBarVerticalGraphTwoColorFilling,JKQTPBarHorizontalGraphTwoColorFilling/--smallscreenshotplot
wiggleplots/JKQTPFilledCurveXGraph_wiggle,JKQTPFilledCurveYGraph_wiggle
contourplot/JKQTPColumnContourPlot/--smallscreenshotplot
filledgraphs/JKQTPFilledCurveXGraph,JKQTPFilledCurveYGraph/--smallscreenshotplot
diff --git a/doc/dox/examples_and_tutorials.dox b/doc/dox/examples_and_tutorials.dox
index 35b576738e..8f860e4c07 100644
--- a/doc/dox/examples_and_tutorials.dox
+++ b/doc/dox/examples_and_tutorials.dox
@@ -40,6 +40,9 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
\image html stackedbars_small.png
| \subpage JKQTPlotterStackedBarChart
| `JKQTPBarVerticalStackableGraph`, `JKQTPBarHorizontalStackableGraph` C++-style vectors of data
diff --git a/doc/dox/todo.dox b/doc/dox/todo.dox
index 418b591071..589e3edb6e 100644
--- a/doc/dox/todo.dox
+++ b/doc/dox/todo.dox
@@ -15,7 +15,6 @@ This page lists several todos and wishes for future version of JKQTPlotter
styling: style.ini with glowing colors in dark background ("techno" or "cyberpunk")
plot: axis labels above/below/centered around tick
plot: elongated grid to left of tick labels
- graphs: different styles above/below baseline for barcharts ...
graphs: vector field graph (arrows), variant (x,y,dx,dy), (x,y,alpha,length), (x1,y1,x2,y2) ... different head/tail styles
graphs: gant-chart as simplufier vector field with (x,y1,y2) or (x1,x2,y), or (x,y,dx), (x,y,dy) ... different head/tail style
graphs: barchart/ranges chart with (x,y1,y2) or (x1,x2,y)
diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox
index 5942431a9d..7661e8505f 100644
--- a/doc/dox/whatsnew.dox
+++ b/doc/dox/whatsnew.dox
@@ -47,6 +47,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
NEW: added the option to register a custom symbol using JKQTPRegisterCustomGraphSymbol()
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
JKQTMathText:
diff --git a/doc/images/JKQTPBarHorizontalGraphTwoColorFilling.png b/doc/images/JKQTPBarHorizontalGraphTwoColorFilling.png
new file mode 100644
index 0000000000..97699b5abe
Binary files /dev/null and b/doc/images/JKQTPBarHorizontalGraphTwoColorFilling.png differ
diff --git a/doc/images/JKQTPBarHorizontalGraphTwoColorFilling_small.png b/doc/images/JKQTPBarHorizontalGraphTwoColorFilling_small.png
new file mode 100644
index 0000000000..a85e5a4d64
Binary files /dev/null and b/doc/images/JKQTPBarHorizontalGraphTwoColorFilling_small.png differ
diff --git a/doc/images/JKQTPBarVerticalGraphTwoColorFilling.png b/doc/images/JKQTPBarVerticalGraphTwoColorFilling.png
new file mode 100644
index 0000000000..8f2737bfe2
Binary files /dev/null and b/doc/images/JKQTPBarVerticalGraphTwoColorFilling.png differ
diff --git a/doc/images/JKQTPBarVerticalGraphTwoColorFilling_small.png b/doc/images/JKQTPBarVerticalGraphTwoColorFilling_small.png
new file mode 100644
index 0000000000..6b39ac7dea
Binary files /dev/null and b/doc/images/JKQTPBarVerticalGraphTwoColorFilling_small.png differ
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index daf33071d6..8f738627ce 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_twocolor)
add_subdirectory(contourplot)
add_subdirectory(datastore)
add_subdirectory(datastore_groupedstat)
diff --git a/examples/barchart_twocolor/CMakeLists.txt b/examples/barchart_twocolor/CMakeLists.txt
new file mode 100644
index 0000000000..9b3fb43520
--- /dev/null
+++ b/examples/barchart_twocolor/CMakeLists.txt
@@ -0,0 +1,34 @@
+cmake_minimum_required(VERSION 3.16)
+
+set(EXAMPLE_NAME barchart_twocolor)
+set(EXENAME jkqtptest_${EXAMPLE_NAME})
+
+message( STATUS ".. Building Example ${EXAMPLE_NAME}" )
+
+
+# Set up source files
+set(SOURCES barchart_twocolor.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_twocolor/README.md b/examples/barchart_twocolor/README.md
new file mode 100644
index 0000000000..7184225481
--- /dev/null
+++ b/examples/barchart_twocolor/README.md
@@ -0,0 +1,44 @@
+# Example (JKQTPlotter): Barchart With Two-Color Fill-Mode {#JKQTPlotterBarchartsTwoColorFilling}
+This project (see [`barchart_twocolor`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/barchart_twocolor) shows how to draw barcharts, where the bars are filled differently if their value is above or below the baseline.
+
+The source code of the main application is (see [`barchart_twocolor.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/barchart_twocolor/barchart_twocolor.cpp):
+```.cpp
+ // 1. create a plotter window and get a pointer to the internal datastore (for convenience)
+ JKQTPlotter plot;
+ JKQTPDatastore* ds=plot.getDatastore();
+
+ // 2. now we create two columns for key and value
+ size_t columnK=ds->addLinearColumn(10, 0, 2.0*JKQTPSTATISTICS_PI,"k");
+ size_t columnV=ds->addColumnCalculatedFromColumn(columnK, &cos, "v");
+
+ // 3. create graph in the plot, which plots the dataset:
+ JKQTPBarGraphBase* graph=new JKQTPBarVerticalGraph(&plot);
+ graph->setKeyColumn(columnK);
+ graph->setValueColumn(columnV);
+ // set TwoColor fill Mode
+ graph->setFillMode(JKQTPBarGraphBase::FillMode::TwoColorFilling);
+ graph->setFillColor(QColor("green"));
+ graph->fillStyleBelow().setFillColor(QColor("red"));
+ plot.addGraph(graph);
+
+ // 4 autoscale the plot so the graph is contained
+ plot.zoomToFit();
+
+ // 5. show plotter and make it a decent size
+ plot.setWindowTitle(title);
+ plot.show();
+ plot.resize(400,400);
+```
+
+
+The result looks like this:
+
+![barchart_twocolor](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/barchart_twocolor.png)
+
+
+
+In order to draw horizontal error bars, you have to use `JKQTPBarHorizontalGraph` instead of `JKQTPBarVerticalGraph`:
+
+![barchart_twocolor_hor](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/barchart_twocolor_hor.png)
+
+
diff --git a/examples/barchart_twocolor/barchart_twocolor.cpp b/examples/barchart_twocolor/barchart_twocolor.cpp
new file mode 100644
index 0000000000..7eab3af058
--- /dev/null
+++ b/examples/barchart_twocolor/barchart_twocolor.cpp
@@ -0,0 +1,58 @@
+/** \example barchart_twocolor.cpp
+ * Shows how to draw Barcharts with different colors above and below the baseline in a JKQTPlotter
+ *
+ * \ref JKQTPlotterBarchartsTwoColorFilling
+ */
+
+#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 two columns for key and value
+ size_t columnK=ds->addLinearColumn(15, 0.5*JKQTPSTATISTICS_PI, 3.0*JKQTPSTATISTICS_PI,"k");
+ size_t columnV=ds->addColumnCalculatedFromColumn(columnK, &cos, "v");
+
+ // 3. create graph in the plot, which plots the dataset:
+ JKQTPBarGraphBase* graph=new TCHART(&plot);
+ graph->setKeyColumn(columnK);
+ graph->setValueColumn(columnV);
+ // set TwoColor fill Mode
+ graph->setFillMode(JKQTPBarGraphBase::FillMode::TwoColorFilling);
+ graph->setFillColor(QColor("green"));
+ graph->fillStyleBelow().setFillColor(QColor("red"));
+ plot.addGraph(graph);
+
+ // 4 autoscale the plot so the graph is contained
+ plot.zoomToFit();
+
+ // 5. show plotter and make it a decent size
+ 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: JKQTPBarVerticalGraph");
+ doExample(plotH, "2: JKQTPBarHorizontalGraph");
+
+ return app.exec();
+}
diff --git a/lib/jkqtplotter/graphs/jkqtpbarchart.cpp b/lib/jkqtplotter/graphs/jkqtpbarchart.cpp
index b73447a8bd..a39704a038 100644
--- a/lib/jkqtplotter/graphs/jkqtpbarchart.cpp
+++ b/lib/jkqtplotter/graphs/jkqtpbarchart.cpp
@@ -60,6 +60,7 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
const QPen p=getLinePenForRects(painter, parent);
const QBrush b=getFillBrush(painter, parent);
+ const QBrush b_below=(getFillMode()==FillMode::TwoColorFilling)?fillStyleBelow().getFillBrush(painter, parent):b;
int imax=0;
int imin=0;
@@ -80,7 +81,8 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
const double xv=datastore->get(static_cast(xColumn),static_cast(i));
const int sr=datastore->getNextLowerIndex(xColumn, i);
const int lr=datastore->getNextHigherIndex(xColumn, i);
- double yv=datastore->get(static_cast(yColumn),static_cast(i));
+ const double yvdirect=datastore->get(static_cast(yColumn),static_cast(i));
+ double yv=yvdirect;
double yv0=y0;
if (!qFuzzyIsNull(getBaseline())) yv0=transformY(getBaseline());
if (hasStackPar) {
@@ -112,9 +114,10 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
//std::cout<<"delta="< to this function.
@@ -164,6 +169,10 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalErrorGraph: public JKQTPBarVertical
\image html JKQTPBarHorizontalGraph.png
+ You can also set JKQTPBarGraphBase::FillMode::TwoColorFilling, which uses different fill styles for bars above and below
+ the baseline of the graph:
+
+ \image html JKQTPBarHorizontalGraphTwoColorFilling.png
\see \ref JKQTPlotterBarcharts, jkqtpstatAddVHistogram1D(), jkqtpstatAddVHistogram1DAutoranged()
*/
diff --git a/lib/jkqtplotter/graphs/jkqtpbarchartbase.cpp b/lib/jkqtplotter/graphs/jkqtpbarchartbase.cpp
index 3fd60e57ff..f73fcd723d 100644
--- a/lib/jkqtplotter/graphs/jkqtpbarchartbase.cpp
+++ b/lib/jkqtplotter/graphs/jkqtpbarchartbase.cpp
@@ -37,10 +37,11 @@
JKQTPBarGraphBase::JKQTPBarGraphBase(JKQTBasePlotter* parent):
- JKQTPXYBaselineGraph(parent), width(0.9), shift(0)
+ JKQTPXYBaselineGraph(parent), width(0.9), shift(0), m_fillMode(FillMode::SingleFilling)
{
initFillStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Barchart);
initLineStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Barchart);
+ m_fillStyleBelow.initFillStyleInvertedColor(this);
}
@@ -112,6 +113,7 @@ void JKQTPBarGraphBase::setColor(QColor c)
setFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphsStyle.barchartStyle.fillColorDerivationMode, c));
c.setAlphaF(0.5);
setHighlightingLineColor(c);
+ m_fillStyleBelow.initFillStyleInvertedColor(this);
}
void JKQTPBarGraphBase::setShift(double __value)
@@ -140,6 +142,26 @@ void JKQTPBarGraphBase::setFillColor_and_darkenedColor(QColor fill, int colorDar
setLineColor(fill.darker(colorDarker));
}
+JKQTPGraphFillStyleMixin &JKQTPBarGraphBase::fillStyleBelow()
+{
+ return m_fillStyleBelow;
+}
+
+const JKQTPGraphFillStyleMixin &JKQTPBarGraphBase::fillStyleBelow() const
+{
+ return m_fillStyleBelow;
+}
+
+JKQTPBarGraphBase::FillMode JKQTPBarGraphBase::getFillMode() const
+{
+ return m_fillMode;
+}
+
+void JKQTPBarGraphBase::setFillMode(FillMode mode)
+{
+ m_fillMode=mode;
+}
+
double JKQTPBarGraphBase::getParentStackedMax(int /*index*/) const
{
return getBaseline();
diff --git a/lib/jkqtplotter/graphs/jkqtpbarchartbase.h b/lib/jkqtplotter/graphs/jkqtpbarchartbase.h
index da899062cd..653747500d 100644
--- a/lib/jkqtplotter/graphs/jkqtpbarchartbase.h
+++ b/lib/jkqtplotter/graphs/jkqtpbarchartbase.h
@@ -50,13 +50,25 @@
*
* \image html JKQTPBarVerticalGraph.png
*
+ * You can also set FillMode::TwoColorFilling, which uses different fill styles for bars above and below
+ * the baseline of the graph:
*
+ * \image html JKQTPBarVerticalGraphTwoColorFilling.png
*
* \see JKQTPBarHorizontalGraph, JKQTPBarVerticalGraph
*/
class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
Q_OBJECT
public:
+ /** \brief specifies how the area below the graph is filled
+ *
+ * \see setFillMode(), getFillMode(), fillStyleBelow(), \ref JKQTPlotterWigglePlots
+ */
+ enum FillMode {
+ SingleFilling=0, /*!< \brief the whole area is filled with the same color/pattern \image html JKQTPBarVerticalGraph.png */
+ TwoColorFilling=1 /*!< \brief the area above and below baseline with the two different colors/pattern \image html JKQTPBarVerticalGraphTwoColorFilling.png */
+ };
+ Q_ENUM(FillMode)
/** \brief class constructor */
JKQTPBarGraphBase(JKQTBasePlotter* parent=nullptr);
/** \brief class constructor */
@@ -84,7 +96,15 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
/** \brief returns xColumn or yColumn, whichever is used for the height of the bars (depending on whether the barchart is vertical or horizontal \see getBarPositionColumn(), xColumn, yColumn */
virtual int getBarHeightColumn() const =0;
+ /** \copydoc m_fillStyleBelow */
+ JKQTPGraphFillStyleMixin &fillStyleBelow();
+ /** \copydoc m_fillStyleBelow */
+ const JKQTPGraphFillStyleMixin& fillStyleBelow() const;
+ /** \copydoc m_fillMode */
+ FillMode getFillMode() const;
public slots:
+ /** \copydoc m_fillMode */
+ void setFillMode(JKQTPBarGraphBase::FillMode mode);
/** \brief finds all bar charts of the same orientation and determines width and shift, so they stand side by side
*
@@ -134,6 +154,11 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
* \image html bargraph_basics.png
*/
double shift;
+ /** \brief specifies how the area of the graph is filles */
+ FillMode m_fillMode;
+ /** \brief if m_fillMode \c ==FillAboveAndBelowDifferently then this fill style is used below the baseline and
+ * the default fill style is used above */
+ JKQTPGraphFillStyleMixin m_fillStyleBelow;
/** \brief this function is used by autoscaleBarWidthAndShift() to determine whether a given graph shall be taken into account when autoscaling.
diff --git a/screenshots/barchart_twocolor.png b/screenshots/barchart_twocolor.png
new file mode 100644
index 0000000000..f5d11d6400
Binary files /dev/null and b/screenshots/barchart_twocolor.png differ
diff --git a/screenshots/barchart_twocolor_hor.png b/screenshots/barchart_twocolor_hor.png
new file mode 100644
index 0000000000..1c5ab26910
Binary files /dev/null and b/screenshots/barchart_twocolor_hor.png differ
diff --git a/screenshots/barchart_twocolor_hor_small.png b/screenshots/barchart_twocolor_hor_small.png
new file mode 100644
index 0000000000..a85e5a4d64
Binary files /dev/null and b/screenshots/barchart_twocolor_hor_small.png differ
diff --git a/screenshots/barchart_twocolor_small.png b/screenshots/barchart_twocolor_small.png
new file mode 100644
index 0000000000..6b39ac7dea
Binary files /dev/null and b/screenshots/barchart_twocolor_small.png differ
|