NEW: you can provide a custom draw functor to barcharts to completely customize their look
@ -144,6 +144,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
|
||||
barchart_twocolor/barchart_twocolor,barchart_twocolor_hor
|
||||
barchart_errorbars/barchart_errorbars,barchart_errorbars_hor
|
||||
barchart_functorfill/barchart_functorfill,barchart_functorfill_hor
|
||||
barchart_customdrawfunctor/barchart_customdrawfunctor,barchart_customdrawfunctor_hor
|
||||
wiggleplots/wiggleplot_x,wiggleplot_y
|
||||
advplotstyling/advancedlineandfillstyling
|
||||
boxplot
|
||||
@ -196,6 +197,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
|
||||
barchart_twocolor/JKQTPBarVerticalGraphTwoColorFilling,JKQTPBarHorizontalGraphTwoColorFilling/--smallscreenshotplot
|
||||
barchart_errorbars/JKQTPBarVerticalErrorGraph,JKQTPBarHorizontalErrorGraph/--smallscreenshotplot
|
||||
barchart_functorfill/JKQTPBarVerticalGraphFunctorFilling,JKQTPBarHorizontalGraphFunctorFilling/--smallscreenshotplot
|
||||
barchart_customdrawfunctor/JKQTPBarVerticalGraphCustomDrawFunctor,JKQTPBarHorizontalGraphCustomDrawFunctor/--smallscreenshotplot
|
||||
wiggleplots/JKQTPFilledCurveXGraph_wiggle,JKQTPFilledCurveYGraph_wiggle
|
||||
contourplot/JKQTPColumnContourPlot/--smallscreenshotplot
|
||||
filledgraphs/JKQTPFilledCurveXGraph,JKQTPFilledCurveYGraph/--smallscreenshotplot
|
||||
|
@ -46,9 +46,12 @@ 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
|
||||
<tr><td> \image html barchart_customdrawfunctor_small.png
|
||||
<td> \subpage JKQTPlotterBarchartsFunctorFilling
|
||||
<td> `JKQTPBarVerticalGraph` <br> JKQTPDatastore::addColumnCalculatedFromColumn()
|
||||
<tr><td> \image html barchart_functorfill_small.png
|
||||
<td> \subpage JKQTPlotterBarchartsCustomDrawFunctor
|
||||
<td> `JKQTPBarVerticalGraph` <br> JKQTPDatastore::addColumnCalculatedFromColumn()
|
||||
<tr><td> \image html stackedbars_small.png
|
||||
<td> \subpage JKQTPlotterStackedBarChart
|
||||
<td> `JKQTPBarVerticalStackableGraph`, `JKQTPBarHorizontalStackableGraph` <br> C++-style vectors of data
|
||||
|
@ -26,7 +26,7 @@ This page lists several todos and wishes for future version of JKQTPlotter
|
||||
<li>plot: elongated grid to left of tick labels</li>
|
||||
<li>plot: legend positioning as combination of 3 values: inside|outside + left|center|right + top|vcenter|bottom</li>
|
||||
<li>plot: refactor print preview/export preview code </li>
|
||||
<li>plot: reqork layouting of legends: there are some inconsistencies/too large gaps ...</li>
|
||||
<li>plot: rework layouting of legends: there are some inconsistencies/too large gaps ...</li>
|
||||
<li>plot: secondary axes: independent and dependent (i.e. with transformation function from primary axis)</li>
|
||||
<li>sryling: better styling/more styling options for data-tooltips</li>
|
||||
<li>styling: color gradients as fill-styles in style-INIs</li>
|
||||
|
@ -64,6 +64,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
<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>
|
||||
<li>NEW: you can provide a custom draw functor to barcharts to completely customize their look</li>
|
||||
</ul></li>
|
||||
|
||||
<li>JKQTMathText:<ul>
|
||||
|
BIN
doc/images/JKQTPBarHorizontalGraphCustomDrawFunctor.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
doc/images/JKQTPBarHorizontalGraphCustomDrawFunctor_small.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
doc/images/JKQTPBarVerticalGraphCustomDrawFunctor.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
doc/images/JKQTPBarVerticalGraphCustomDrawFunctor_small.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
@ -51,6 +51,7 @@ add_subdirectory(boxplot)
|
||||
add_subdirectory(barchart_errorbars)
|
||||
add_subdirectory(barchart_functorfill)
|
||||
add_subdirectory(barchart_twocolor)
|
||||
add_subdirectory(barchart_customdrawfunctor)
|
||||
add_subdirectory(contourplot)
|
||||
add_subdirectory(datastore)
|
||||
add_subdirectory(datastore_groupedstat)
|
||||
|
34
examples/barchart_customdrawfunctor/CMakeLists.txt
Normal file
@ -0,0 +1,34 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(EXAMPLE_NAME barchart_customdrawfunctor)
|
||||
set(EXENAME jkqtptest_${EXAMPLE_NAME})
|
||||
|
||||
message( STATUS ".. Building Example ${EXAMPLE_NAME}" )
|
||||
|
||||
|
||||
# Set up source files
|
||||
set(SOURCES barchart_customdrawfunctor.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})
|
89
examples/barchart_customdrawfunctor/README.md
Normal file
@ -0,0 +1,89 @@
|
||||
# Example (JKQTPlotter): Barchart With Custom Draw Functor {#JKQTPlotterBarchartsCustomDrawFunctor}
|
||||
This project (see [`barchart_customdrawfunctor`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/barchart_customdrawfunctor) shows how to draw customized barcharts, with a custom draw functor.
|
||||
|
||||
The source code of the main application is (see [`barchart_customdrawfunctor.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/barchart_customdrawfunctor/barchart_customdrawfunctor.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(7, 0, 6, "k");
|
||||
size_t columnV=ds->addColumnCalculatedFromColumn(columnK, [](double x) { return jkqtp_sign(2.0*x-2.5)*qMax(2.0,fabs(2.0*x-2.5)); }, "v");
|
||||
|
||||
// 3. load a stylesheet
|
||||
plot.loadCurrentPlotterStyle(QSettings(":/JKQTPlotter/styles/seaborn.ini", QSettings::IniFormat));
|
||||
|
||||
// 4. create graph in the plot, which plots the dataset:
|
||||
JKQTPBarVerticalGraph* graph=new JKQTPBarVerticalGraph(&plot);
|
||||
graph->setKeyColumn(columnK);
|
||||
graph->setValueColumn(columnV);
|
||||
// this is the custom draw functor
|
||||
graph->setCustomDrawingFunctor(
|
||||
[](JKQTPEnhancedPainter& painter, const QRectF& bar_px, const QPointF& datapoint, Qt::Orientation orientation, JKQTPBarGraphBase* graph) {
|
||||
painter.save();
|
||||
painter.setPen(Qt::NoPen);
|
||||
QBrush b=painter.brush();
|
||||
QBrush bDeco=b;
|
||||
bDeco.setColor(b.color().lighter());
|
||||
// we draw the bar with a rounded end and add a lightly colored circle near the top
|
||||
if (orientation==Qt::Vertical) {
|
||||
// for vertical barcharts
|
||||
const double dx=bar_px.width()/2.0;
|
||||
const double r=dx*0.85;
|
||||
// depending in whether the bar elongates above or below the baseline,
|
||||
// we have to align the circle wrt the top or the bottom of the rectangle bar_px
|
||||
if (datapoint.y()>=graph->getBaseline()) {
|
||||
painter.drawComplexRoundedRect(bar_px, dx, dx, 0, 0, Qt::AbsoluteSize);
|
||||
painter.setBrush(bDeco);
|
||||
painter.drawEllipse(QPointF(bar_px.center().x(), bar_px.top()+dx), r,r);
|
||||
} else {
|
||||
painter.drawComplexRoundedRect(bar_px, 0, 0, dx, dx, Qt::AbsoluteSize);
|
||||
painter.setBrush(bDeco);
|
||||
painter.drawEllipse(QPointF(bar_px.center().x(), bar_px.bottom()-dx), r,r);
|
||||
}
|
||||
} else {
|
||||
// for horizontal barcharts
|
||||
const double dx=bar_px.height()/2.0;
|
||||
const double r=dx*0.85;
|
||||
if (datapoint.x()>=graph->getBaseline()) {
|
||||
painter.drawComplexRoundedRect(bar_px, 0, dx, 0, dx, Qt::AbsoluteSize);
|
||||
painter.setBrush(bDeco);
|
||||
painter.drawEllipse(QPointF(bar_px.right()-dx, bar_px.center().y()), r,r);
|
||||
} else {
|
||||
painter.drawComplexRoundedRect(bar_px, dx,0,dx,0, Qt::AbsoluteSize);
|
||||
painter.setBrush(bDeco);
|
||||
painter.drawEllipse(QPointF(bar_px.left()+dx, bar_px.center().y()), r,r);
|
||||
}
|
||||
}
|
||||
painter.restore();
|
||||
}
|
||||
);
|
||||
// enable usage of cutom draw functor
|
||||
graph->setUseCustomDrawFunctor(true);
|
||||
// set graph color
|
||||
graph->setColor(QColor("blue"));
|
||||
plot.addGraph(graph);
|
||||
|
||||
|
||||
// 5. autoscale the plot so the graph is contained
|
||||
plot.zoomToFit();
|
||||
|
||||
// 6. show plotter and make it a decent size
|
||||
plot.setWindowTitle(title);
|
||||
plot.show();
|
||||
plot.resize(400,400);
|
||||
```
|
||||
|
||||
|
||||
|
||||
The result looks like this:
|
||||
|
||||
![barchart_customdrawfunctor](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/barchart_customdrawfunctor.png)
|
||||
|
||||
|
||||
|
||||
In order to draw horizontal error bars, you have to use `JKQTPBarHorizontalGraph` instead of `JKQTPBarVerticalGraph`. The functor given above also covers that case by checking the parameter `orientation`:
|
||||
|
||||
![barchart_customdrawfunctor_hor](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/barchart_customdrawfunctor_hor.png)
|
||||
|
||||
|
@ -0,0 +1,102 @@
|
||||
/** \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/jkqtpbarchart.h"
|
||||
#include "jkqtcommon/jkqtpmathtools.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(7, 0, 6, "k");
|
||||
size_t columnV=ds->addColumnCalculatedFromColumn(columnK, [](double x) { return jkqtp_sign(2.0*x-2.5)*qMax(2.0,fabs(2.0*x-2.5)); }, "v");
|
||||
|
||||
// 3. load a stylesheet
|
||||
plot.loadCurrentPlotterStyle(QSettings(":/JKQTPlotter/styles/seaborn.ini", QSettings::IniFormat));
|
||||
|
||||
// 4. create graph in the plot, which plots the dataset:
|
||||
JKQTPBarGraphBase* graph=new TCHART(&plot);
|
||||
graph->setKeyColumn(columnK);
|
||||
graph->setValueColumn(columnV);
|
||||
// this is the custom draw functor
|
||||
graph->setCustomDrawingFunctor(
|
||||
[](JKQTPEnhancedPainter& painter, const QRectF& bar_px, const QPointF& datapoint, Qt::Orientation orientation, JKQTPBarGraphBase* graph) {
|
||||
painter.save();
|
||||
painter.setPen(Qt::NoPen);
|
||||
QBrush b=painter.brush();
|
||||
QBrush bDeco=b;
|
||||
bDeco.setColor(b.color().lighter());
|
||||
// we draw the bar with a rounded end and add a lightly colored circle near the top
|
||||
if (orientation==Qt::Vertical) {
|
||||
// for vertical barcharts
|
||||
const double dx=bar_px.width()/2.0;
|
||||
const double r=dx*0.85;
|
||||
// depending in whether the bar elongates above or below the baseline,
|
||||
// we have to align the circle wrt the top or the bottom of the rectangle bar_px
|
||||
if (datapoint.y()>=graph->getBaseline()) {
|
||||
painter.drawComplexRoundedRect(bar_px, dx, dx, 0, 0, Qt::AbsoluteSize);
|
||||
painter.setBrush(bDeco);
|
||||
painter.drawEllipse(QPointF(bar_px.center().x(), bar_px.top()+dx), r,r);
|
||||
} else {
|
||||
painter.drawComplexRoundedRect(bar_px, 0, 0, dx, dx, Qt::AbsoluteSize);
|
||||
painter.setBrush(bDeco);
|
||||
painter.drawEllipse(QPointF(bar_px.center().x(), bar_px.bottom()-dx), r,r);
|
||||
}
|
||||
} else {
|
||||
// for horizontal barcharts
|
||||
const double dx=bar_px.height()/2.0;
|
||||
const double r=dx*0.85;
|
||||
if (datapoint.x()>=graph->getBaseline()) {
|
||||
painter.drawComplexRoundedRect(bar_px, 0, dx, 0, dx, Qt::AbsoluteSize);
|
||||
painter.setBrush(bDeco);
|
||||
painter.drawEllipse(QPointF(bar_px.right()-dx, bar_px.center().y()), r,r);
|
||||
} else {
|
||||
painter.drawComplexRoundedRect(bar_px, dx,0,dx,0, Qt::AbsoluteSize);
|
||||
painter.setBrush(bDeco);
|
||||
painter.drawEllipse(QPointF(bar_px.left()+dx, bar_px.center().y()), r,r);
|
||||
}
|
||||
}
|
||||
painter.restore();
|
||||
}
|
||||
);
|
||||
// enable usage of cutom draw functor
|
||||
graph->setUseCustomDrawFunctor(true);
|
||||
// set graph color
|
||||
graph->setColor(QColor("blue"));
|
||||
plot.addGraph(graph);
|
||||
|
||||
|
||||
// 5. autoscale the plot so the graph is contained
|
||||
plot.zoomToFit();
|
||||
|
||||
// 6. 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();
|
||||
}
|
@ -11,7 +11,7 @@ The source code of the main application is (see [`barchart_functorfill.cpp`](htt
|
||||
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);
|
||||
JKQTPBarVerticalGraph* graph=new JKQTPBarVerticalGraph(&plot);
|
||||
graph->setKeyColumn(columnK);
|
||||
graph->setValueColumn(columnV);
|
||||
// set FunctorFilling fill Mode
|
||||
|
@ -121,21 +121,26 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||
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);
|
||||
//qDebug()<<"r="<<r<<", rectRadiusAtBaseline="<<rectRadiusAtBaseline<<", rectRadiusAtValue="<<rectRadiusAtValue<<", rAtBaseline="<<rAtBaseline<<", rAtValue="<<rAtValue;
|
||||
if (rAtBaseline+rAtValue>=r.height()+2) {
|
||||
//qDebug()<<"drawRect";
|
||||
painter.drawRect(r);
|
||||
if (usesCustomDrawFunctor()) {
|
||||
if (m_customDrawFunctor) {
|
||||
m_customDrawFunctor(painter, r, QPointF(xv,yv), Qt::Vertical, this);
|
||||
}
|
||||
} else {
|
||||
//qDebug()<<"drawRoundRect swapped="<<swapped;
|
||||
if (swapped) {
|
||||
painter.drawComplexRoundedRect(r,rAtBaseline,rAtBaseline,rAtValue,rAtValue,Qt::AbsoluteSize);
|
||||
const double rAtBaseline=parent->pt2px(painter, rectRadiusAtBaseline);
|
||||
const double rAtValue=parent->pt2px(painter, rectRadiusAtValue);
|
||||
//qDebug()<<"r="<<r<<", rectRadiusAtBaseline="<<rectRadiusAtBaseline<<", rectRadiusAtValue="<<rectRadiusAtValue<<", rAtBaseline="<<rAtBaseline<<", rAtValue="<<rAtValue;
|
||||
if (rAtBaseline+rAtValue>=r.height()+2) {
|
||||
//qDebug()<<"drawRect";
|
||||
painter.drawRect(r);
|
||||
} else {
|
||||
painter.drawComplexRoundedRect(r,rAtValue,rAtValue,rAtBaseline,rAtBaseline,Qt::AbsoluteSize);
|
||||
//qDebug()<<"drawRoundRect swapped="<<swapped;
|
||||
if (swapped) {
|
||||
painter.drawComplexRoundedRect(r,rAtBaseline,rAtBaseline,rAtValue,rAtValue,Qt::AbsoluteSize);
|
||||
} else {
|
||||
painter.drawComplexRoundedRect(r,rAtValue,rAtValue,rAtBaseline,rAtBaseline,Qt::AbsoluteSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -283,17 +288,24 @@ void JKQTPBarHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||
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);
|
||||
if (rAtBaseline+rAtValue>r.width()+2) {
|
||||
painter.drawRect(r);
|
||||
} else {
|
||||
if (swapped) {
|
||||
painter.drawComplexRoundedRect(r,rAtBaseline,rAtValue,rAtBaseline,rAtValue,Qt::AbsoluteSize);
|
||||
} else {
|
||||
painter.drawComplexRoundedRect(r,rAtValue,rAtBaseline,rAtValue,rAtBaseline,Qt::AbsoluteSize);
|
||||
if (usesCustomDrawFunctor()) {
|
||||
if (m_customDrawFunctor) {
|
||||
m_customDrawFunctor(painter, r, QPointF(xv,yv), Qt::Horizontal, this);
|
||||
}
|
||||
} }
|
||||
} else {
|
||||
const double rAtBaseline=parent->pt2px(painter, rectRadiusAtBaseline);
|
||||
const double rAtValue=parent->pt2px(painter, rectRadiusAtBaseline);
|
||||
if (rAtBaseline+rAtValue>r.width()+2) {
|
||||
painter.drawRect(r);
|
||||
} else {
|
||||
if (swapped) {
|
||||
painter.drawComplexRoundedRect(r,rAtBaseline,rAtValue,rAtBaseline,rAtValue,Qt::AbsoluteSize);
|
||||
} else {
|
||||
painter.drawComplexRoundedRect(r,rAtValue,rAtBaseline,rAtValue,rAtBaseline,Qt::AbsoluteSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,26 @@
|
||||
|
||||
\image html JKQTPBarVerticalGraphFunctorFilling.png
|
||||
|
||||
|
||||
You can also completely customize the drawing by defining a custom draw functor:
|
||||
\code
|
||||
graph->setCustomDrawingFunctor(
|
||||
[](JKQTPEnhancedPainter& painter, const QRectF& bar_px, const QPointF& datapoint, Qt::Orientation orientation, JKQTPBarGraphBase* graph) {
|
||||
// draw the bar (if required), pen and brush are already set properly
|
||||
painter.drawRect(bar_px);
|
||||
// now we can add some decoration or replace the instruction above:
|
||||
// ........
|
||||
}
|
||||
);
|
||||
// enable usage of cutom draw functor
|
||||
graph->setUseCustomDrawFunctor(true);
|
||||
\endcode
|
||||
|
||||
See \ref JKQTPlotterBarchartsCustomDrawFunctor for a detailed example.
|
||||
The result may look like this:
|
||||
|
||||
\image html JKQTPBarVerticalGraphCustomDrawFunctor.png
|
||||
|
||||
\see JKQTPBarHorizontalGraph, \ref JKQTPlotterBarcharts, jkqtpstatAddHHistogram1D(), jkqtpstatAddHHistogram1DAutoranged()
|
||||
*/
|
||||
class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalGraph: public JKQTPBarGraphBase {
|
||||
@ -190,6 +210,24 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalErrorGraph: public JKQTPBarVertical
|
||||
|
||||
\image html JKQTPBarHorizontalGraphFunctorFilling.png
|
||||
|
||||
You can also completely customize the drawing by defining a custom draw functor:
|
||||
\code
|
||||
graph->setCustomDrawingFunctor(
|
||||
[](JKQTPEnhancedPainter& painter, const QRectF& bar_px, const QPointF& datapoint, Qt::Orientation orientation, JKQTPBarGraphBase* graph) {
|
||||
// draw the bar (if required), pen and brush are already set properly
|
||||
painter.drawRect(bar_px);
|
||||
// now we can add some decoration or replace the instruction above:
|
||||
// ........
|
||||
}
|
||||
);
|
||||
// enable usage of cutom draw functor
|
||||
graph->setUseCustomDrawFunctor(true);
|
||||
\endcode
|
||||
|
||||
See \ref JKQTPlotterBarchartsCustomDrawFunctor for a detailed example.
|
||||
The result may look like this:
|
||||
|
||||
\image html JKQTPBarHorizontalGraphCustomDrawFunctor.png
|
||||
|
||||
\see \ref JKQTPlotterBarcharts, jkqtpstatAddVHistogram1D(), jkqtpstatAddVHistogram1DAutoranged()
|
||||
*/
|
||||
|
@ -38,6 +38,7 @@ JKQTPBarGraphBase::JKQTPBarGraphBase(JKQTBasePlotter* parent):
|
||||
JKQTPXYBaselineGraph(parent),
|
||||
width(0.9), shift(0),
|
||||
m_fillMode(FillMode::SingleFilling),
|
||||
m_useCustomDrawFunctor(false),
|
||||
m_lineColorDerivationModeForSpecialFill(parent->getCurrentPlotterStyle().graphsStyle.barchartStyle.graphColorDerivationMode),
|
||||
rectRadiusAtBaseline(0),rectRadiusAtValue(0)
|
||||
{
|
||||
@ -57,7 +58,6 @@ JKQTPBarGraphBase::JKQTPBarGraphBase(JKQTPlotter* parent):
|
||||
void JKQTPBarGraphBase::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) {
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
QPen p=getLinePenForRects(painter, parent);
|
||||
QPen np(Qt::NoPen);
|
||||
QBrush b=getFillBrush(painter, parent);
|
||||
//int y=rect.top()+rect.height()/2.0;
|
||||
painter.setPen(p);
|
||||
@ -242,6 +242,21 @@ void JKQTPBarGraphBase::setFillBrushFunctor(SimpleFillBrushFunctor &&f) {
|
||||
m_fillBrushFunctor=SimpleFillBrushFunctorAdaptor(std::forward<SimpleFillBrushFunctor>(f));
|
||||
}
|
||||
|
||||
void JKQTPBarGraphBase::setCustomDrawingFunctor(CustomDrawingFunctor &&f)
|
||||
{
|
||||
m_customDrawFunctor=std::forward<CustomDrawingFunctor>(f);
|
||||
}
|
||||
|
||||
void JKQTPBarGraphBase::setCustomDrawingFunctor(const CustomDrawingFunctor &f)
|
||||
{
|
||||
m_customDrawFunctor=f;
|
||||
}
|
||||
|
||||
void JKQTPBarGraphBase::setUseCustomDrawFunctor(bool enabled)
|
||||
{
|
||||
m_useCustomDrawFunctor=enabled;
|
||||
}
|
||||
|
||||
double JKQTPBarGraphBase::getParentStackedMax(int /*index*/) const
|
||||
{
|
||||
return getBaseline();
|
||||
@ -383,3 +398,8 @@ JKQTPColorDerivationMode JKQTPBarGraphBase::getLineColorDerivationModeForSpecial
|
||||
{
|
||||
return m_lineColorDerivationModeForSpecialFill;
|
||||
}
|
||||
|
||||
bool JKQTPBarGraphBase::usesCustomDrawFunctor() const
|
||||
{
|
||||
return m_useCustomDrawFunctor;
|
||||
}
|
||||
|
@ -67,6 +67,27 @@
|
||||
* The result may look like this:
|
||||
*
|
||||
* \image html JKQTPBarVerticalGraphFunctorFilling.png
|
||||
*
|
||||
* You can also completely customize the drawing by defining a custom draw functor:
|
||||
* \code
|
||||
* graph->setCustomDrawingFunctor(
|
||||
* [](JKQTPEnhancedPainter& painter, const QRectF& bar_px, const QPointF& datapoint, Qt::Orientation orientation, JKQTPBarGraphBase* graph) {
|
||||
* // draw the bar (if required), pen and brush are already set properly
|
||||
* painter.drawRect(bar_px);
|
||||
* // now we can add some decoration or replace the instruction above:
|
||||
* // ........
|
||||
* }
|
||||
* );
|
||||
* // enable usage of cutom draw functor
|
||||
* graph->setUseCustomDrawFunctor(true);
|
||||
* \endcode
|
||||
*
|
||||
* See \ref JKQTPlotterBarchartsCustomDrawFunctor for a detailed example.
|
||||
*
|
||||
* The result may look like this:
|
||||
*
|
||||
* \image html JKQTPBarVerticalGraphCustomDrawFunctor.png
|
||||
|
||||
*
|
||||
* \see JKQTPBarHorizontalGraph, JKQTPBarVerticalGraph
|
||||
*/
|
||||
@ -83,6 +104,9 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
|
||||
* \see setFillBrushFunctor(), getFillBrushFunctor()
|
||||
*/
|
||||
typedef std::function<QBrush(double key, double value)> SimpleFillBrushFunctor;
|
||||
|
||||
/** \brief functor for custom drawing of bars */
|
||||
typedef std::function<void(JKQTPEnhancedPainter& painter, const QRectF& bar_px, const QPointF& datapoint, Qt::Orientation orientation, JKQTPBarGraphBase* graph)> CustomDrawingFunctor;
|
||||
/** \brief specifies how the area below the graph is filled
|
||||
*
|
||||
* \see setFillMode(), getFillMode(), fillStyleBelow(), \ref JKQTPlotterWigglePlots
|
||||
@ -137,6 +161,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
|
||||
const FillBrushFunctor& getFillBrushFunctor() const;
|
||||
/** \copydoc m_lineColorDerivationModeForSpecialFill */
|
||||
JKQTPColorDerivationMode getLineColorDerivationModeForSpecialFill() const;
|
||||
/** \copydoc m_useCustomDrawFunctor */
|
||||
bool usesCustomDrawFunctor() const;
|
||||
|
||||
public slots:
|
||||
/** \copydoc m_fillMode */
|
||||
@ -152,6 +178,13 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
|
||||
/** \copydoc m_fillBrushFunctor */
|
||||
void setFillBrushFunctor(JKQTPBarGraphBase::SimpleFillBrushFunctor&& f);
|
||||
|
||||
/** \copydoc m_customDrawFunctor */
|
||||
void setCustomDrawingFunctor(JKQTPBarGraphBase::CustomDrawingFunctor&& f);
|
||||
/** \copydoc m_customDrawFunctor */
|
||||
void setCustomDrawingFunctor(const JKQTPBarGraphBase::CustomDrawingFunctor& f);
|
||||
/** \copydoc m_useCustomDrawFunctor */
|
||||
void setUseCustomDrawFunctor(bool enabled);
|
||||
|
||||
/** \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
|
||||
@ -263,6 +296,36 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYBaselineGraph, pub
|
||||
* \see setFillBrushFunctor(), getFillBrushFunctor(), m_fillMode
|
||||
*/
|
||||
FillBrushFunctor m_fillBrushFunctor;
|
||||
/** \brief this allows to provide custom drawing code for the bars.
|
||||
* It is called for every visible bar if activated by \c setUseCustomDrawFunctor(true) .
|
||||
*
|
||||
* Here is an example for a custom draw functor:
|
||||
* \code
|
||||
* graph->setCustomDrawingFunctor(
|
||||
* [](JKQTPEnhancedPainter& painter, const QRectF& bar_px, const QPointF& datapoint, Qt::Orientation orientation, JKQTPBarGraphBase* graph) {
|
||||
* // draw the bar (if required), pen and brush are already set properly
|
||||
* painter.drawRect(bar_px);
|
||||
* // now we can add some decoration or replace the instruction above:
|
||||
* // ........
|
||||
* }
|
||||
* );
|
||||
* // enable usage of cutom draw functor
|
||||
* graph->setUseCustomDrawFunctor(true);
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* The result may look like this:
|
||||
*
|
||||
* \image html JKQTPBarVerticalGraphCustomDrawFunctor.png
|
||||
*
|
||||
* \see CustomDrawingFunctor, m_useCustomDrawFunctor, setUseCustomDrawFunctor(), \ref JKQTPlotterBarchartsCustomDrawFunctor for a detailed example
|
||||
*/
|
||||
CustomDrawingFunctor m_customDrawFunctor;
|
||||
/** \brief enabled custom drawing by m_customDrawFunctor
|
||||
*
|
||||
* \see m_customDrawFunctor
|
||||
*/
|
||||
bool m_useCustomDrawFunctor;
|
||||
|
||||
/** \brief returns a FillBrushFunctor that is appropriate for the currently selected m_fillMode */
|
||||
virtual FillBrushFunctor constructFillBrushFunctor() const;
|
||||
|
BIN
screenshots/barchart_customdrawfunctor.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
screenshots/barchart_customdrawfunctor_hor.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
screenshots/barchart_customdrawfunctor_hor_small.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
screenshots/barchart_customdrawfunctor_small.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |