NEW: barcharts can be colored by a user-specified functor

This commit is contained in:
jkriege2 2022-10-22 16:40:44 +02:00
parent 5ed48ea828
commit c6ac8a8cc4
65 changed files with 352 additions and 128 deletions

View File

@ -143,6 +143,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
barchart/barchart,barchart_hor
barchart_twocolor/barchart_twocolor,barchart_twocolor_hor
barchart_errorbars/barchart_errorbars,barchart_errorbars_hor
barchart_functorfill/barchart_functorfill,barchart_functorfill_hor
wiggleplots/wiggleplot_x,wiggleplot_y
advplotstyling/advancedlineandfillstyling
boxplot
@ -194,6 +195,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
barchart/JKQTPBarVerticalGraph,JKQTPBarHorizontalGraph/--smallscreenshotplot
barchart_twocolor/JKQTPBarVerticalGraphTwoColorFilling,JKQTPBarHorizontalGraphTwoColorFilling/--smallscreenshotplot
barchart_errorbars/JKQTPBarVerticalErrorGraph,JKQTPBarHorizontalErrorGraph/--smallscreenshotplot
barchart_functorfill/JKQTPBarVerticalGraphFunctorFilling,JKQTPBarHorizontalGraphFunctorFilling/--smallscreenshotplot
wiggleplots/JKQTPFilledCurveXGraph_wiggle,JKQTPFilledCurveYGraph_wiggle
contourplot/JKQTPColumnContourPlot/--smallscreenshotplot
filledgraphs/JKQTPFilledCurveXGraph,JKQTPFilledCurveYGraph/--smallscreenshotplot

View File

@ -46,6 +46,9 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
<tr><td> \image html barchart_twocolor_small.png
<td> \subpage JKQTPlotterBarchartsTwoColorFilling
<td> `JKQTPBarVerticalGraph` <br> JKQTPDatastore::addColumnCalculatedFromColumn()
<tr><td> \image html barchart_functorfill_small.png
<td> \subpage JKQTPlotterBarchartsFunctorFilling
<td> `JKQTPBarVerticalGraph` <br> JKQTPDatastore::addColumnCalculatedFromColumn()
<tr><td> \image html stackedbars_small.png
<td> \subpage JKQTPlotterStackedBarChart
<td> `JKQTPBarVerticalStackableGraph`, `JKQTPBarHorizontalStackableGraph` <br> C++-style vectors of data

View File

@ -15,12 +15,12 @@ This page lists several todos and wishes for future version of JKQTPlotter
<li>graphs: add candlestick charts (financial, see https://en.m.wikipedia.org/wiki/Candlestick_chart)</li>
<li>graphs: add color palettes from Green's HELIX method, see <a href="https://articles.adsabs.harvard.edu/pdf/2011BASI...39..289G">https://articles.adsabs.harvard.edu/pdf/2011BASI...39..289G</a>, also see <a href="https://jiffyclub.github.io/palettable/cubehelix/">https://jiffyclub.github.io/palettable/cubehelix/</a></li>
<li>graphs: barchart/ranges chart with (x,y1,y2) or (x1,x2,y)</li>
<li>graphs: parametrized barcharts: color from dara</li>
<li>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</li>
<li>graphs: matrix plots with boxes, labels, ...</li>
<li>graphs: matrix plots with symbols: symbol-type, color, size should be parametric, cf. scatter plots</li>
<li>graphs: text labels at positions/for graphs</li>
<li>graphs: vector field graph (arrows), variant (x,y,dx,dy), (x,y,alpha,length), (x1,y1,x2,y2) ... different head/tail styles</li>
<li>graphs: waterfall charts (see https://en.wikipedia.org/wiki/Waterfall_chart)</li>
<li>plot: axes with symlog (see http://dx.doi.org/10.1088/0957-0233/24/2/027001) and logit (https://de.m.wikipedia.org/wiki/Logit) scaling? </li>
<li>plot: axis labels above/below/centered around tick</li>
<li>plot: elongated grid to left of tick labels</li>

View File

@ -52,7 +52,6 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>NEW: added the option to register a custom symbol using JKQTPRegisterCustomGraphSymbol() </li>
<li>NEW: added property drawLineInForeground to JKQTPXYLineGraph and JKQTPXYParametrizedScatterGraph</li>
<li>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.</li>
<li>NEW: barcharts (derived from JKQTPBarGraphBase) can be configured to use different fill styles above and below the baseline, see JKQTPBarGraphBase::FillMode </li>
<li>NEW: added new error indicator styles JKQTPErrorHalfBarsOutwards, JKQTPErrorHalfBarsInwards, JKQTPErrorHalfBarsAbove, JKQTPErrorHalfBarsBelow which are especially useful for barcharts</li>
<li>NEW: Added signals JKQTBasePlotter::beforeExporting()/JKQTBasePlotter::afterExporting() and JKQTBasePlotterJKQTBasePlotter:beforePrinting()/JKQTBasePlotter::afterPrinting() which allow to modify the plot just before and just after an export/print</li>
<li>NEW: Added new JKQTPCALabelType elements (JKQTPCALTfrac...), so axis label ticks can be displayed as fractions 1/2 instead of 0.5<br>
@ -62,7 +61,9 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>NEW: all elements of a coordinate axis may have their own color now </li>
<li>NEW: added possibility to scale the axis ticks by a factor (e.g. pi) to generate axes with ticks <tt>0pi, 1pi, 2pi ...</tt> </li>
<li>NEW: added option to draw a zero axis to JKQTPCoordinateAxis, which draws an axis at the origin of the coordinate system </li>
<li>NEW: barcharts may hav rounded corners now, via JKQTPBarGraphBase::setRectRadius()</li>
<li>NEW: barcharts (derived from JKQTPBarGraphBase) can be configured to use different fill styles above and below the baseline, see JKQTPBarGraphBase::FillMode </li>
<li>NEW: barcharts may have rounded corners now, via JKQTPBarGraphBase::setRectRadius()</li>
<li>NEW: barcharts can be colored by a user-specified functor</li>
</ul></li>
<li>JKQTMathText:<ul>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -49,6 +49,7 @@ add_subdirectory(advplotstyling)
add_subdirectory(barchart)
add_subdirectory(boxplot)
add_subdirectory(barchart_errorbars)
add_subdirectory(barchart_functorfill)
add_subdirectory(barchart_twocolor)
add_subdirectory(contourplot)
add_subdirectory(datastore)

View File

@ -0,0 +1,34 @@
cmake_minimum_required(VERSION 3.16)
set(EXAMPLE_NAME barchart_functorfill)
set(EXENAME jkqtptest_${EXAMPLE_NAME})
message( STATUS ".. Building Example ${EXAMPLE_NAME}" )
# Set up source files
set(SOURCES barchart_functorfill.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})

View File

@ -0,0 +1,47 @@
# Example (JKQTPlotter): Barchart With Functor Fill-Mode {#JKQTPlotterBarchartsFunctorFilling}
This project (see [`barchart_functorfill`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/barchart_functorfill) shows how to draw barcharts, where the bars are filled differently, as defined by a custom functor.
The source code of the main application is (see [`barchart_functorfill.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/barchart_functorfill/barchart_functorfill.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 two columns for key and value
size_t columnK=ds->addLinearColumn(11, 0, 10, "k");
size_t columnV=ds->addColumnCalculatedFromColumn(columnK, [](double x) { return 5.0+x; }, "v");
// 3. create graph in the plot, which plots the dataset:
JKQTPBarGraphBase* graph=new TCHART(&plot);
graph->setKeyColumn(columnK);
graph->setValueColumn(columnV);
// set FunctorFilling fill Mode
graph->setFillMode(JKQTPBarGraphBase::FillMode::FunctorFilling);
// define filling functor
graph->setFillBrushFunctor(
[](double key, double value) {
return QBrush(QColor::fromHsvF(key/12.0, 1.0, 1.0));
}
);
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_functorfill](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/barchart_functorfill.png)
In order to draw horizontal error bars, you have to use `JKQTPBarHorizontalGraph` instead of `JKQTPBarVerticalGraph`:
![barchart_functorfill_hor](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/barchart_functorfill_hor.png)

View File

@ -0,0 +1,56 @@
/** \example barchart_functorfill.cpp
* Shows how to draw Barcharts with colors defined by a functor JKQTPlotter
*
* \ref JKQTPlotterBarchartsFunctorFilling
*/
#include "jkqtpexampleapplication.h"
#include <QApplication>
#include "jkqtplotter/jkqtplotter.h"
#include "jkqtplotter/graphs/jkqtpscatter.h"
#include "jkqtplotter/graphs/jkqtpbarchart.h"
#include "jkqtpexampleapplication.h"
template <class TCHART>
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(11, 0, 10, "k");
size_t columnV=ds->addColumnCalculatedFromColumn(columnK, [](double x) { return 5.0+x; }, "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::FunctorFilling);
graph->setFillBrushFunctor([](double key, double value) {return QBrush(QColor::fromHsvF(key/12.0, 1.0, 1.0)); });
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<JKQTPBarVerticalGraph>(plotV, "1: JKQTPBarVerticalGraph");
doExample<JKQTPBarHorizontalGraph>(plotH, "2: JKQTPBarHorizontalGraph");
return app.exec();
}

View File

@ -25,8 +25,6 @@
#include <QDebug>
#include <iostream>
#include "jkqtplotter/jkqtptools.h"
#include "jkqtplotter/graphs/jkqtpimage.h"
#include "jkqtplotter/jkqtpbaseelements.h"
#include "jkqtplotter/jkqtplotter.h"
#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
@ -59,8 +57,7 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
drawErrorsBefore(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;
const auto fillFunctor=std::bind(constructFillBrushFunctor(), std::placeholders::_1, std::placeholders::_2, std::ref(painter), this);
int imax=0;
int imin=0;
@ -115,9 +112,14 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
bool swapped=false;
if (yy<y) { qSwap(y,yy); swapped=true; }
if (JKQTPIsOKFloat(x) && JKQTPIsOKFloat(xx) && JKQTPIsOKFloat(y) && JKQTPIsOKFloat(yy)) {
if (yvdirect<getBaseline()) painter.setBrush(b_below);
else painter.setBrush(b);
painter.setPen(p);
const QBrush b=fillFunctor(xv,yv);
painter.setBrush(b);
if (getFillMode()!=FillMode::SingleFilling) {
QPen pl=p;
pl.setColor(JKQTPGetDerivedColor(m_lineColorDerivationModeForSpecialFill,b.color()));
} else {
painter.setPen(p);
}
const QRectF r(QPointF(x, y), QPointF(xx, yy));
const double rAtBaseline=parent->pt2px(painter, rectRadiusAtBaseline);
const double rAtValue=parent->pt2px(painter, rectRadiusAtValue);
@ -150,35 +152,6 @@ bool JKQTPBarVerticalGraph::getYMinMax(double& miny, double& maxy, double& small
return getValuesMinMax(miny, maxy, smallestGreaterZero);
}
int JKQTPBarVerticalGraph::getBarPositionColumn() const
{
return xColumn;
}
int JKQTPBarVerticalGraph::getBarHeightColumn() const
{
return yColumn;
}
void JKQTPBarVerticalGraph::setBarPositionColumn(int column)
{
xColumn=column;
}
void JKQTPBarVerticalGraph::setBarPositionColumn(size_t column)
{
xColumn=static_cast<int>(column);
}
void JKQTPBarVerticalGraph::setBarHeightColumn(int column)
{
yColumn=column;
}
void JKQTPBarVerticalGraph::setBarHeightColumn(size_t column)
{
yColumn=static_cast<int>(column);
}
bool JKQTPBarVerticalGraph::considerForAutoscaling(JKQTPBarGraphBase *other) const
{
@ -206,54 +179,25 @@ JKQTPBarHorizontalGraph::JKQTPBarHorizontalGraph(JKQTPlotter *parent):
}
int JKQTPBarHorizontalGraph::getBarPositionColumn() const
int JKQTPBarHorizontalGraph::getKeyColumn() const
{
return yColumn;
}
int JKQTPBarHorizontalGraph::getBarHeightColumn() const
int JKQTPBarHorizontalGraph::getValueColumn() const
{
return xColumn;
}
int JKQTPBarHorizontalGraph::getKeyColumn() const
{
return getBarPositionColumn();
}
int JKQTPBarHorizontalGraph::getValueColumn() const
{
return getBarHeightColumn();
}
void JKQTPBarHorizontalGraph::setKeyColumn(int __value)
{
setBarPositionColumn(__value);
yColumn=__value;
}
void JKQTPBarHorizontalGraph::setValueColumn(int __value)
{
setBarHeightColumn(__value);
}
void JKQTPBarHorizontalGraph::setBarPositionColumn(int column)
{
yColumn=column;
}
void JKQTPBarHorizontalGraph::setBarPositionColumn(size_t column)
{
yColumn=static_cast<int>(column);
}
void JKQTPBarHorizontalGraph::setBarHeightColumn(int column)
{
xColumn=column;
}
void JKQTPBarHorizontalGraph::setBarHeightColumn(size_t column)
{
xColumn=static_cast<int>(column);
xColumn=__value;
}
bool JKQTPBarHorizontalGraph::considerForAutoscaling(JKQTPBarGraphBase *other) const
@ -272,8 +216,7 @@ void JKQTPBarHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
drawErrorsBefore(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;
const auto fillFunctor=std::bind(constructFillBrushFunctor(), std::placeholders::_1, std::placeholders::_2, std::ref(painter), this);
int imax=0;
int imin=0;
@ -331,9 +274,14 @@ void JKQTPBarHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
//qDebug()<<"delta="<<delta<<" x="<<x<<" y="<<y<<" xx="<<xx<<" yy="<<yy;
//qDebug()<<"xv="<<xv<<" x0="<<x0<<" x="<<x<<"..."<<xx;
if (JKQTPIsOKFloat(x) && JKQTPIsOKFloat(xx) && JKQTPIsOKFloat(y) && JKQTPIsOKFloat(yy)) {
if (xvdirect<getBaseline()) painter.setBrush(b_below);
else painter.setBrush(b);
painter.setPen(p);
const QBrush b=fillFunctor(yv,xv);
painter.setBrush(b);
if (getFillMode()!=FillMode::SingleFilling) {
QPen pl=p;
pl.setColor(JKQTPGetDerivedColor(m_lineColorDerivationModeForSpecialFill,b.color()));
} else {
painter.setPen(p);
}
const QRectF r(QPointF(x, y), QPointF(xx, yy));
const double rAtBaseline=parent->pt2px(painter, rectRadiusAtBaseline);
const double rAtValue=parent->pt2px(painter, rectRadiusAtBaseline);

View File

@ -26,7 +26,6 @@
#include <QPair>
#include "jkqtplotter/jkqtptools.h"
#include "jkqtplotter/jkqtplotter_imexport.h"
#include "jkqtplotter/jkqtpimagetools.h"
#include "jkqtplotter/jkqtpgraphsbase.h"
#include "jkqtplotter/jkqtpgraphsbaseerrors.h"
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
@ -84,25 +83,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalGraph: public JKQTPBarGraphBase {
* The result is given in the two parameters which are call-by-reference parameters!
*/
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
/** \brief returns xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual int getBarPositionColumn() const override;
/** \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 override;
public slots:
/** \brief returns xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual void setBarPositionColumn(int column) override;
/** \brief returns xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual void setBarPositionColumn(size_t column) override;
/** \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 void setBarHeightColumn(int column) override;
/** \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 void setBarHeightColumn(size_t column) override;
protected:
@ -206,12 +188,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarHorizontalGraph: public JKQTPBarGraphBase {
* The result is given in the two parameters which are call-by-reference parameters!
*/
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
/** \brief returns xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual int getBarPositionColumn() const override;
/** \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 override;
/** \brief returns the column used as "key" for the current graph (typically this call getXColumn(), but for horizontal graphs like filled curves or barcharts it may call getYColumn() ) */
virtual int getKeyColumn() const override;
/** \brief returns the column used as "value" for the current graph (typically this call getXColumn(), but for horizontal graphs like filled curves or barcharts it may call getYColumn() ) */
@ -221,18 +197,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarHorizontalGraph: public JKQTPBarGraphBase {
virtual void setKeyColumn(int __value) override;
/** \brief sets the column used as "value" for the current graph (typically this call setXColumn(), but for horizontal graphs like filled curves or barcharts it may call setYColumn() ) */
virtual void setValueColumn(int __value) override;
/** \brief sets xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual void setBarPositionColumn(int column) override;
/** \brief sets xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual void setBarPositionColumn(size_t column) override;
/** \brief sets 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 void setBarHeightColumn(int column) override;
/** \brief sets 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 void setBarHeightColumn(size_t column) override;
protected:
/** \brief this function is used by autoscaleBarWidthAndShift() to determine whether a given graph shall be taken into account when autoscaling.

View File

@ -35,7 +35,11 @@
JKQTPBarGraphBase::JKQTPBarGraphBase(JKQTBasePlotter* parent):
JKQTPXYBaselineGraph(parent), width(0.9), shift(0), m_fillMode(FillMode::SingleFilling),rectRadiusAtBaseline(0),rectRadiusAtValue(0)
JKQTPXYBaselineGraph(parent),
width(0.9), shift(0),
m_fillMode(FillMode::SingleFilling),
m_lineColorDerivationModeForSpecialFill(parent->getCurrentPlotterStyle().graphsStyle.barchartStyle.graphColorDerivationMode),
rectRadiusAtBaseline(0),rectRadiusAtValue(0)
{
initFillStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Barchart);
initLineStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Barchart);
@ -109,13 +113,45 @@ void JKQTPBarGraphBase::autoscaleBarWidthAndShiftSeparatedGroups(double groupWid
void JKQTPBarGraphBase::setColor(QColor c)
{
setLineColor(c);
setFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphsStyle.barchartStyle.fillColorDerivationMode, c));
setFillColor(c);
setLineColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphsStyle.barchartStyle.graphColorDerivationMode, c));
c.setAlphaF(0.5);
setHighlightingLineColor(c);
m_fillStyleBelow.initFillStyleInvertedColor(this);
}
void JKQTPBarGraphBase::setBarPositionColumn(int column)
{
setKeyColumn(column);
}
void JKQTPBarGraphBase::setBarPositionColumn(size_t column)
{
setKeyColumn(static_cast<int>(column));
}
void JKQTPBarGraphBase::setBarHeightColumn(int column)
{
setValueColumn(column);
}
void JKQTPBarGraphBase::setBarHeightColumn(size_t column)
{
setValueColumn(static_cast<int>(column));
}
JKQTPBarGraphBase::FillBrushFunctor JKQTPBarGraphBase::constructFillBrushFunctor() const
{
if (m_fillMode==FillMode::FunctorFilling) return m_fillBrushFunctor;
if (m_fillMode==FillMode::TwoColorFilling) return [](double , double value, JKQTPEnhancedPainter &painter, JKQTPBarGraphBase* graph) {
if (value<graph->getBaseline()) return graph->fillStyleBelow().getFillBrush(painter, graph->getParent());
return graph->getFillBrush(painter, graph->getParent());
};
else return [](double, double, JKQTPEnhancedPainter &painter, JKQTPBarGraphBase* graph) {
return graph->getFillBrush(painter, graph->getParent());
};
}
void JKQTPBarGraphBase::setShift(double __value)
{
this->shift = __value;
@ -142,6 +178,16 @@ void JKQTPBarGraphBase::setFillColor_and_darkenedColor(QColor fill, int colorDar
setLineColor(fill.darker(colorDarker));
}
int JKQTPBarGraphBase::getBarPositionColumn() const
{
return getKeyColumn();
}
int JKQTPBarGraphBase::getBarHeightColumn() const
{
return getValueColumn();
}
JKQTPGraphFillStyleMixin &JKQTPBarGraphBase::fillStyleBelow()
{
return m_fillStyleBelow;
@ -167,11 +213,35 @@ double JKQTPBarGraphBase::getRectRadiusAtBaseline() const
return rectRadiusAtBaseline;
}
JKQTPBarGraphBase::FillBrushFunctor &JKQTPBarGraphBase::getFillBrushFunctor() {
return m_fillBrushFunctor;
}
const JKQTPBarGraphBase::FillBrushFunctor &JKQTPBarGraphBase::getFillBrushFunctor() const {
return m_fillBrushFunctor;
}
void JKQTPBarGraphBase::setFillMode(FillMode mode)
{
m_fillMode=mode;
}
void JKQTPBarGraphBase::setFillBrushFunctor(const FillBrushFunctor &f) {
m_fillBrushFunctor=f;
}
void JKQTPBarGraphBase::setFillBrushFunctor(FillBrushFunctor &&f) {
m_fillBrushFunctor=std::forward<FillBrushFunctor>(f);
}
void JKQTPBarGraphBase::setFillBrushFunctor(const SimpleFillBrushFunctor &f) {
m_fillBrushFunctor=SimpleFillBrushFunctorAdaptor(f);
}
void JKQTPBarGraphBase::setFillBrushFunctor(SimpleFillBrushFunctor &&f) {
m_fillBrushFunctor=SimpleFillBrushFunctorAdaptor(std::forward<SimpleFillBrushFunctor>(f));
}
double JKQTPBarGraphBase::getParentStackedMax(int /*index*/) const
{
return getBaseline();
@ -303,3 +373,13 @@ void JKQTPBarGraphBase::setRectRadius(double atValue, double atBaseline)
setRectRadiusAtValue(atValue);
setRectRadiusAtBaseline(atBaseline);
}
void JKQTPBarGraphBase::setLineColorDerivationModeForSpecialFill(const JKQTPColorDerivationMode &m)
{
m_lineColorDerivationModeForSpecialFill=m;
}
JKQTPColorDerivationMode JKQTPBarGraphBase::getLineColorDerivationModeForSpecialFill() const
{
return m_lineColorDerivationModeForSpecialFill;
}

View File

@ -23,11 +23,10 @@
#include <QString>
#include <QPainter>
#include <QPair>
#include <functional>
#include "jkqtplotter/jkqtptools.h"
#include "jkqtplotter/jkqtplotter_imexport.h"
#include "jkqtplotter/jkqtpimagetools.h"
#include "jkqtplotter/jkqtpgraphsbase.h"
#include "jkqtplotter/jkqtpgraphsbaseerrors.h"
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
@ -55,20 +54,46 @@
*
* \image html JKQTPBarVerticalGraphTwoColorFilling.png
*
* If you use FillMode::FunctorFilling you can specify the fill style by a functor, e.g.
* \code
* graph->setFillMode(JKQTPBarGraphBase::FillMode::FunctorFilling);
* graph->setFillBrushFunctor(
* [](double key, double value) {
* return QBrush(QColor::fromHsvF(key/12.0, 1.0, 1.0));
* }
* );
* \endcode
*
* The result may look like this:
*
* \image html JKQTPBarVerticalGraphFunctorFilling.png
*
* \see JKQTPBarHorizontalGraph, JKQTPBarVerticalGraph
*/
class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
Q_OBJECT
public:
/** \brief a type of functor for FillMode::FunctorFilling
*
* \see setFillBrushFunctor(), getFillBrushFunctor()
*/
typedef std::function<QBrush(double key, double value,JKQTPEnhancedPainter &painter, JKQTPBarGraphBase* graph)> FillBrushFunctor;
/** \brief a simplified type of functor for FillMode::FunctorFilling
*
* \see setFillBrushFunctor(), getFillBrushFunctor()
*/
typedef std::function<QBrush(double key, double value)> SimpleFillBrushFunctor;
/** \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 */
TwoColorFilling=1, /*!< \brief the area above and below baseline with the two different colors/pattern \image html JKQTPBarVerticalGraphTwoColorFilling.png */
FunctorFilling=2, /*!< \brief a functor (use setFillBrushFunctor() to define one) is used to determine the fill color\image html JKQTPBarVerticalGraphFunctorFilling.png */
};
Q_ENUM(FillMode)
/** \brief class constructor */
JKQTPBarGraphBase(JKQTBasePlotter* parent=nullptr);
/** \brief class constructor */
@ -92,10 +117,10 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
void setFillColor_and_darkenedColor(QColor fill, int colorDarker=200);
/** \brief returns xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual int getBarPositionColumn() const =0;
int getBarPositionColumn() const;
/** \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;
int getBarHeightColumn() const;
/** \copydoc m_fillStyleBelow */
JKQTPGraphFillStyleMixin &fillStyleBelow();
/** \copydoc m_fillStyleBelow */
@ -106,11 +131,27 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
double getRectRadiusAtValue() const;
/** \copydoc rectRadiusAtBaseline */
double getRectRadiusAtBaseline() const;
/** \copydoc m_fillBrushFunctor */
FillBrushFunctor& getFillBrushFunctor();
/** \copydoc m_fillBrushFunctor */
const FillBrushFunctor& getFillBrushFunctor() const;
/** \copydoc m_lineColorDerivationModeForSpecialFill */
JKQTPColorDerivationMode getLineColorDerivationModeForSpecialFill() const;
public slots:
/** \copydoc m_fillMode */
void setFillMode(JKQTPBarGraphBase::FillMode mode);
/** \copydoc m_fillBrushFunctor */
void setFillBrushFunctor(const JKQTPBarGraphBase::FillBrushFunctor& f);
/** \copydoc m_fillBrushFunctor */
void setFillBrushFunctor(JKQTPBarGraphBase::FillBrushFunctor&& f);
/** \copydoc m_fillBrushFunctor */
void setFillBrushFunctor(const JKQTPBarGraphBase::SimpleFillBrushFunctor& f);
/** \copydoc m_fillBrushFunctor */
void setFillBrushFunctor(JKQTPBarGraphBase::SimpleFillBrushFunctor&& f);
/** \brief finds all bar charts of the same orientation and determines width and shift, so they stand side by side
*
* \param maxWidth the maximum (relative) width, that all bars will span of the (doubled) inter-bar distance
@ -137,6 +178,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
/** \brief sets the corner radius of the bars for both ends */
void setRectRadius(double atValue, double atBaseline);
/** \copydoc m_lineColorDerivationModeForSpecialFill */
void setLineColorDerivationModeForSpecialFill(const JKQTPColorDerivationMode& m);
/** \brief set outline and fill color at the same time
* \see setFillColor_and_darkenedColor()
@ -145,17 +188,18 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
/** \brief returns xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual void setBarPositionColumn(int column) =0;
void setBarPositionColumn(int column) ;
/** \brief returns xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual void setBarPositionColumn(size_t column) =0;
void setBarPositionColumn(size_t column) ;
/** \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 void setBarHeightColumn(int column) =0;
void setBarHeightColumn(int column) ;
/** \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 void setBarHeightColumn(size_t column) =0;
void setBarHeightColumn(size_t column) ;
protected:
/** \brief the width of the bargraphs, relative to the distance between the current and the next x-value
*
* See the following graphic to understand this concept:
@ -172,12 +216,56 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
double rectRadiusAtValue;
/** \brief corner radius (in pt) for bars at the "baseline" end */
double rectRadiusAtBaseline;
/** \brief specifies how the area of the graph is filles */
/** \brief specifies how the area of the graph is filles
*
* \note If any fill style other than FillStyle::SingleFill is used, the peroperty m_lineColorDerivationModeForSpecialFill
* is used to derive the color of the bars' outlines from the fill color.
*
* \see setFillMode(), getFillMode(), m_fillStyleBelow, m_fillBrushFunctor, m_lineColorDerivationModeForSpecialFill
*/
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 */
* the default fill style is used above
*
* \see fillStyleBelow() , setFillMode()
*/
JKQTPGraphFillStyleMixin m_fillStyleBelow;
/** \brief defines how to derive the line color in m_fillMode!=SingleFilling
*
* \see setLineColorDerivationModeForSpecialFill(), setFillMode(), getLineColorDerivationModeForSpecialFill(), FillMode
*/
JKQTPColorDerivationMode m_lineColorDerivationModeForSpecialFill;
/** \brief adapter that converts a SimpleFillBrushFunctor to a FillBrushFunctor */
struct SimpleFillBrushFunctorAdaptor {
inline SimpleFillBrushFunctorAdaptor(const SimpleFillBrushFunctor& f): m_f(f) {}
inline SimpleFillBrushFunctorAdaptor(SimpleFillBrushFunctor&& f): m_f(std::forward<SimpleFillBrushFunctor>(f)) {}
SimpleFillBrushFunctor m_f;
inline QBrush operator()(double key, double value,JKQTPEnhancedPainter &, JKQTPBarGraphBase*) { return m_f(key,value);}
};
/** \brief functor, used to determine the color in m_fillMode==FunctorFilling
*
* If you use FillMode::FunctorFilling you can specify the fill style by a functor, e.g.
* \code
* graph->setFillMode(JKQTPBarGraphBase::FillMode::FunctorFilling);
* graph->setFillBrushFunctor(
* [](double key, double value) {
* return QBrush(QColor::fromHsvF(key/12.0, 1.0, 1.0));
* }
* );
* \endcode
*
* The result may look like this:
*
* \image html JKQTPBarVerticalGraphFunctorFilling.png
*
* \see setFillBrushFunctor(), getFillBrushFunctor(), m_fillMode
*/
FillBrushFunctor m_fillBrushFunctor;
/** \brief returns a FillBrushFunctor that is appropriate for the currently selected m_fillMode */
virtual FillBrushFunctor constructFillBrushFunctor() const;
/** \brief this function is used by autoscaleBarWidthAndShift() to determine whether a given graph shall be taken into account when autoscaling.
* Typically this returns \c true for all JKQTPBarGraphBase-derved objects with the same orientation (horizontal or vertical) */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB