mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-11-15 18:15:52 +08:00
reworked class hierarchy of bar charts
This commit is contained in:
parent
4c98310147
commit
9dbfd6e173
@ -25,7 +25,8 @@ Changes, compared to \ref page_whatsnew_V2019_11 "v2019.11" include:
|
|||||||
<li>removed/breaking change: removed the overlay elements (derived from JKQTPOverlayElement), which were not very well set up and are more confusing than useful.</li>
|
<li>removed/breaking change: removed the overlay elements (derived from JKQTPOverlayElement), which were not very well set up and are more confusing than useful.</li>
|
||||||
<li>improved/breaking change: geometric objects now use an adaptive drawing algorithm to represent curves (before e.g. ellipses were always separated into a fixed number of line-segments)</li>
|
<li>improved/breaking change: geometric objects now use an adaptive drawing algorithm to represent curves (before e.g. ellipses were always separated into a fixed number of line-segments)</li>
|
||||||
<li>improved: constructors and access functions for several geometric objects (e.g. more constructors, additional functions to retrieve parameters in diferent forms, iterators for polygons, ...)</li>
|
<li>improved: constructors and access functions for several geometric objects (e.g. more constructors, additional functions to retrieve parameters in diferent forms, iterators for polygons, ...)</li>
|
||||||
<li>improved/breaking change: reworked class hirarchy of parsed function plots and declared several setters as slots.</li>
|
<li>improved/breaking change: reworked class hierarchy of parsed function plots and declared several setters as slots.</li>
|
||||||
|
<li>improved/breaking change: reworked class hierarchy of bar charts.</li>
|
||||||
<li>bugfixed/improved: aspect ratio handling in JKQTPlotter.</li>
|
<li>bugfixed/improved: aspect ratio handling in JKQTPlotter.</li>
|
||||||
<li>new: added geometric plot objects JKQTPGeoArrow to draw arrows (aka lines with added line-end decorators, also extended JKQTPGeoLine, JKQTPGeoInfiniteLine, JKQTPGeoPolyLines to draw line-end decorator (aka arrows)</li>
|
<li>new: added geometric plot objects JKQTPGeoArrow to draw arrows (aka lines with added line-end decorators, also extended JKQTPGeoLine, JKQTPGeoInfiniteLine, JKQTPGeoPolyLines to draw line-end decorator (aka arrows)</li>
|
||||||
<li>new: all geometric objects can either be drawn as graphic element (i.e. lines are straight line, even on non-linear axes), or as mathematical curve (i.e. on non-linear axes, lines become the appropriate curve representing the linear function, connecting the given start/end-points). The only exceptions are ellipses (and the derived arcs,pies,chords), which are always drawn as mathematical curves</li>
|
<li>new: all geometric objects can either be drawn as graphic element (i.e. lines are straight line, even on non-linear axes), or as mathematical curve (i.e. on non-linear axes, lines become the appropriate curve representing the linear function, connecting the given start/end-points). The only exceptions are ellipses (and the derived arcs,pies,chords), which are always drawn as mathematical curves</li>
|
||||||
|
@ -89,8 +89,17 @@ int main(int argc, char* argv[])
|
|||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note: Here we use the functions `JKQTPBarVerticalGraph::setXColumn()` and `JKQTPBarVerticalGraph::setYColumn()` to set the columns to use for the stack positions (X) and heights (Y). Instead you can also use the semantic version `JKQTPBarGraphBase::setBarPositionColumn()` and `JKQTPBarGraphBase::setBarHeightColumn()`.
|
||||||
|
|
||||||
The result looks like this:
|
The result looks like this:
|
||||||
|
|
||||||
![barchart](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/barchart.png)
|
![barchart](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/barchart.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
In order to draw horizontal error bars, you have to use `JKQTPBarHorizontalGraph` instead of `JKQTPBarVerticalGraph`:
|
||||||
|
|
||||||
|
![barchart](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/barchart_hor.png)
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,16 +10,17 @@
|
|||||||
#include "jkqtplotter/graphs/jkqtpbarchart.h"
|
#include "jkqtplotter/graphs/jkqtpbarchart.h"
|
||||||
|
|
||||||
#define Ndata 5
|
#define Ndata 5
|
||||||
int main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class TCHART>
|
||||||
|
void doExample()
|
||||||
|
{
|
||||||
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
|
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
|
||||||
JKQTPlotter plot;
|
JKQTPlotter* plot=new JKQTPlotter();
|
||||||
plot.getPlotter()->setUseAntiAliasingForGraphs(true); // nicer (but slower) plotting
|
plot->getPlotter()->setUseAntiAliasingForGraphs(true); // nicer (but slower) plotting
|
||||||
plot.getPlotter()->setUseAntiAliasingForSystem(true); // nicer (but slower) plotting
|
plot->getPlotter()->setUseAntiAliasingForSystem(true); // nicer (but slower) plotting
|
||||||
plot.getPlotter()->setUseAntiAliasingForText(true); // nicer (but slower) text rendering
|
plot->getPlotter()->setUseAntiAliasingForText(true); // nicer (but slower) text rendering
|
||||||
JKQTPDatastore* ds=plot.getDatastore();
|
JKQTPDatastore* ds=plot->getDatastore();
|
||||||
|
|
||||||
// 2. now we create data for three simple barchart
|
// 2. now we create data for three simple barchart
|
||||||
QString L[Ndata]={ "cat. A", "cat. C", "cat. B", "cat. D", "other"}; // unsorted category axis
|
QString L[Ndata]={ "cat. A", "cat. C", "cat. B", "cat. D", "other"}; // unsorted category axis
|
||||||
@ -41,24 +42,24 @@ int main(int argc, char* argv[])
|
|||||||
size_t columnY3=ds->addCopiedColumn(Y3, Ndata, "y3");
|
size_t columnY3=ds->addCopiedColumn(Y3, Ndata, "y3");
|
||||||
|
|
||||||
// 4. create graphs in the plot, which plots the dataset X/Y1, X/Y2 and X/Y3:
|
// 4. create graphs in the plot, which plots the dataset X/Y1, X/Y2 and X/Y3:
|
||||||
JKQTPBarVerticalGraph* graph1=new JKQTPBarVerticalGraph(&plot);
|
TCHART* graph1=new TCHART(plot);
|
||||||
graph1->setXColumn(columnX);
|
graph1->setBarPositionColumn(columnX);
|
||||||
graph1->setYColumn(columnY1);
|
graph1->setBarHeightColumn(columnY1);
|
||||||
graph1->setTitle(QObject::tr("dataset 1"));
|
graph1->setTitle(QObject::tr("dataset 1"));
|
||||||
JKQTPBarVerticalGraph* graph2=new JKQTPBarVerticalGraph(&plot);
|
TCHART* graph2=new TCHART(plot);
|
||||||
graph2->setXColumn(columnX);
|
graph2->setBarPositionColumn(columnX);
|
||||||
graph2->setYColumn(columnY2);
|
graph2->setBarHeightColumn(columnY2);
|
||||||
graph2->setTitle(QObject::tr("dataset 2"));
|
graph2->setTitle(QObject::tr("dataset 2"));
|
||||||
JKQTPBarVerticalGraph* graph3=new JKQTPBarVerticalGraph(&plot);
|
TCHART* graph3=new TCHART(plot);
|
||||||
graph3->setXColumn(columnX);
|
graph3->setBarPositionColumn(columnX);
|
||||||
graph3->setYColumn(columnY3);
|
graph3->setBarHeightColumn(columnY3);
|
||||||
graph3->setTitle(QObject::tr("dataset 3"));
|
graph3->setTitle(QObject::tr("dataset 3"));
|
||||||
|
|
||||||
|
|
||||||
// 5. add the graphs to the plot, so it is actually displayed
|
// 5. add the graphs to the plot, so it is actually displayed
|
||||||
plot.addGraph(graph1);
|
plot->addGraph(graph1);
|
||||||
plot.addGraph(graph2);
|
plot->addGraph(graph2);
|
||||||
plot.addGraph(graph3);
|
plot->addGraph(graph3);
|
||||||
|
|
||||||
// 6. now we set the graphs, so they are plotted side-by-side
|
// 6. now we set the graphs, so they are plotted side-by-side
|
||||||
// This function searches all JKQTPBarHorizontalGraph in the current
|
// This function searches all JKQTPBarHorizontalGraph in the current
|
||||||
@ -66,29 +67,45 @@ int main(int argc, char* argv[])
|
|||||||
// side-by-side groups
|
// side-by-side groups
|
||||||
graph1->autoscaleBarWidthAndShift(0.75, 1);
|
graph1->autoscaleBarWidthAndShift(0.75, 1);
|
||||||
|
|
||||||
|
if (dynamic_cast<JKQTPBarVerticalGraph*>(graph1)!=nullptr) {
|
||||||
// 7. data is grouped into 5 numbere groups (1..5), but we also have string
|
// 7. data is grouped into 5 numbere groups (1..5), but we also have string
|
||||||
// labels for these groups (stored in L). In order to display these labels,
|
// labels for these groups (stored in L). In order to display these labels,
|
||||||
// we have to tell the x-Axis to use these special labels:
|
// we have to tell the x-Axis to use these special labels:
|
||||||
plot.getXAxis()->addAxisTickLabels(X, L, Ndata);
|
plot->getXAxis()->addAxisTickLabels(X, L, Ndata);
|
||||||
// also we can rotate the labels a bit (by 45 degree), so they fit better
|
// also we can rotate the labels a bit (by 45 degree), so they fit better
|
||||||
plot.getXAxis()->setTickLabelAngle(45);
|
plot->getXAxis()->setTickLabelAngle(45);
|
||||||
plot.getXAxis()->setTickLabelFontSize(12);
|
plot->getXAxis()->setTickLabelFontSize(12);
|
||||||
|
} else {
|
||||||
|
// 7. data is grouped into 5 numbere groups (1..5), but we also have string
|
||||||
|
// labels for these groups (stored in L). In order to display these labels,
|
||||||
|
// we have to tell the x-Axis to use these special labels:
|
||||||
|
plot->getYAxis()->addAxisTickLabels(X, L, Ndata);
|
||||||
|
plot->getYAxis()->setTickLabelFontSize(12);
|
||||||
|
}
|
||||||
|
|
||||||
// 8. finally we move the plot key/legend to the outside, top-right
|
// 8. finally we move the plot key/legend to the outside, top-right
|
||||||
// and lay it out as a single row
|
// and lay it out as a single row
|
||||||
// NOTE: plot is a descendent of QWidget, which uses an internal object of
|
// NOTE: plot is a descendent of QWidget, which uses an internal object of
|
||||||
// type JKQTBasePlotter, which does the actual plotting.
|
// type JKQTBasePlotter, which does the actual plotting.
|
||||||
// So many properties of the plot are only available in this internal
|
// So many properties of the plot are only available in this internal
|
||||||
// object, which you can access by plot.getPlotter().
|
// object, which you can access by plot->getPlotter().
|
||||||
plot.getPlotter()->setKeyPosition(JKQTPKeyOutsideTopRight);
|
plot->getPlotter()->setKeyPosition(JKQTPKeyOutsideTopRight);
|
||||||
plot.getPlotter()->setKeyLayout(JKQTPKeyLayoutOneRow);
|
plot->getPlotter()->setKeyLayout(JKQTPKeyLayoutOneRow);
|
||||||
|
|
||||||
// 9 autoscale the plot so the graph is contained
|
// 9 autoscale the plot so the graph is contained
|
||||||
plot.zoomToFit();
|
plot->zoomToFit();
|
||||||
|
|
||||||
// show plotter and make it a decent size
|
// show plotter and make it a decent size
|
||||||
plot.show();
|
plot->show();
|
||||||
plot.resize(600,400);
|
plot->resize(600,400);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
doExample<JKQTPBarVerticalGraph>();
|
||||||
|
doExample<JKQTPBarHorizontalGraph>();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ isEmpty(JKQTP_PLOTTER_PRI_INCLUDED) {
|
|||||||
$$PWD/jkqtplotter/graphs/jkqtpscatter.h \
|
$$PWD/jkqtplotter/graphs/jkqtpscatter.h \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtprange.h \
|
$$PWD/jkqtplotter/graphs/jkqtprange.h \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpspecialline.h \
|
$$PWD/jkqtplotter/graphs/jkqtpspecialline.h \
|
||||||
|
$$PWD/jkqtplotter/graphs/jkqtpbarchartbase.h \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpbarchart.h \
|
$$PWD/jkqtplotter/graphs/jkqtpbarchart.h \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpevaluatedparametriccurve.h \
|
$$PWD/jkqtplotter/graphs/jkqtpevaluatedparametriccurve.h \
|
||||||
$$PWD/jkqtplotter/gui/jkqtpcomboboxes.h \
|
$$PWD/jkqtplotter/gui/jkqtpcomboboxes.h \
|
||||||
@ -97,6 +98,7 @@ isEmpty(JKQTP_PLOTTER_PRI_INCLUDED) {
|
|||||||
$$PWD/jkqtplotter/graphs/jkqtpscatter.cpp \
|
$$PWD/jkqtplotter/graphs/jkqtpscatter.cpp \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtprange.cpp \
|
$$PWD/jkqtplotter/graphs/jkqtprange.cpp \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpspecialline.cpp \
|
$$PWD/jkqtplotter/graphs/jkqtpspecialline.cpp \
|
||||||
|
$$PWD/jkqtplotter/graphs/jkqtpbarchartbase.cpp \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpbarchart.cpp \
|
$$PWD/jkqtplotter/graphs/jkqtpbarchart.cpp \
|
||||||
$$PWD/jkqtplotter/graphs/jkqtpevaluatedparametriccurve.cpp \
|
$$PWD/jkqtplotter/graphs/jkqtpevaluatedparametriccurve.cpp \
|
||||||
$$PWD/jkqtplotter/gui/jkqtpcomboboxes.cpp \
|
$$PWD/jkqtplotter/gui/jkqtpcomboboxes.cpp \
|
||||||
|
@ -40,6 +40,7 @@ set(SOURCES_GRAPHS
|
|||||||
graphs/jkqtpscatter.cpp
|
graphs/jkqtpscatter.cpp
|
||||||
graphs/jkqtprange.cpp
|
graphs/jkqtprange.cpp
|
||||||
graphs/jkqtpspecialline.cpp
|
graphs/jkqtpspecialline.cpp
|
||||||
|
graphs/jkqtpbarchartbase.cpp
|
||||||
graphs/jkqtpbarchart.cpp
|
graphs/jkqtpbarchart.cpp
|
||||||
graphs/jkqtpboxplot.cpp
|
graphs/jkqtpboxplot.cpp
|
||||||
graphs/jkqtpboxplotstylingmixins.cpp
|
graphs/jkqtpboxplotstylingmixins.cpp
|
||||||
@ -115,6 +116,7 @@ set(HEADERS_GRAPHS
|
|||||||
graphs/jkqtpscatter.h
|
graphs/jkqtpscatter.h
|
||||||
graphs/jkqtprange.h
|
graphs/jkqtprange.h
|
||||||
graphs/jkqtpspecialline.h
|
graphs/jkqtpspecialline.h
|
||||||
|
graphs/jkqtpbarchartbase.h
|
||||||
graphs/jkqtpbarchart.h
|
graphs/jkqtpbarchart.h
|
||||||
graphs/jkqtpevaluatedparametriccurve.h
|
graphs/jkqtpevaluatedparametriccurve.h
|
||||||
)
|
)
|
||||||
|
@ -37,14 +37,9 @@
|
|||||||
|
|
||||||
|
|
||||||
JKQTPBarVerticalGraph::JKQTPBarVerticalGraph(JKQTBasePlotter* parent):
|
JKQTPBarVerticalGraph::JKQTPBarVerticalGraph(JKQTBasePlotter* parent):
|
||||||
JKQTPXYGraph(parent)
|
JKQTPBarGraphBase(parent)
|
||||||
{
|
{
|
||||||
baseline=0.0;
|
|
||||||
width=0.9;
|
|
||||||
shift=0;
|
|
||||||
|
|
||||||
initFillStyle(parent, parentPlotStyle);
|
|
||||||
initLineStyle(parent, parentPlotStyle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -53,23 +48,6 @@ JKQTPBarVerticalGraph::JKQTPBarVerticalGraph(JKQTPlotter* parent):
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void JKQTPBarVerticalGraph::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);
|
|
||||||
painter.setBrush(b);
|
|
||||||
painter.drawRect(rect);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor JKQTPBarVerticalGraph::getKeyLabelColor() const {
|
|
||||||
return getFillColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
|
void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||||
#ifdef JKQTBP_AUTOTIMER
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
JKQTPAutoOutputTimer jkaaot("JKQTPBarHorizontalGraph::draw");
|
JKQTPAutoOutputTimer jkaaot("JKQTPBarHorizontalGraph::draw");
|
||||||
@ -158,139 +136,46 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool JKQTPBarVerticalGraph::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) {
|
bool JKQTPBarVerticalGraph::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) {
|
||||||
bool start=true;
|
return getPositionsMinMax(minx, maxx, smallestGreaterZero);
|
||||||
minx=0;
|
|
||||||
maxx=0;
|
|
||||||
smallestGreaterZero=0;
|
|
||||||
|
|
||||||
if (parent==nullptr) return false;
|
|
||||||
|
|
||||||
JKQTPDatastore* datastore=parent->getDatastore();
|
|
||||||
int imin=0;
|
|
||||||
int imax=static_cast<int>(qMin(datastore->getRows(static_cast<size_t>(xColumn)), datastore->getRows(static_cast<size_t>(yColumn))));
|
|
||||||
if (imax<imin) {
|
|
||||||
int h=imin;
|
|
||||||
imin=imax;
|
|
||||||
imax=h;
|
|
||||||
}
|
|
||||||
if (imin<0) imin=0;
|
|
||||||
if (imax<0) imax=0;
|
|
||||||
|
|
||||||
for (int i=imin; i<imax; i++) {
|
|
||||||
double xv=datastore->get(static_cast<size_t>(xColumn),static_cast<size_t>(i));
|
|
||||||
int sr=datastore->getNextLowerIndex(xColumn, i);
|
|
||||||
int lr=datastore->getNextHigherIndex(xColumn, i);
|
|
||||||
double delta, deltap, deltam;
|
|
||||||
|
|
||||||
if (sr<0 && lr<0) { // only one x-value
|
|
||||||
deltam=0.5;
|
|
||||||
deltap=0.5;
|
|
||||||
} else if (lr<0) { // the right-most x-value
|
|
||||||
deltap=deltam=fabs(xv-datastore->get(xColumn,sr))/2.0;
|
|
||||||
} else if (sr<0) { // the left-most x-value
|
|
||||||
deltam=deltap=fabs(datastore->get(xColumn,lr)-xv)/2.0;
|
|
||||||
} else {
|
|
||||||
deltam=fabs(xv-datastore->get(xColumn,sr))/2.0;
|
|
||||||
deltap=fabs(datastore->get(xColumn,lr)-xv)/2.0;
|
|
||||||
}
|
|
||||||
delta=deltap+deltam;
|
|
||||||
|
|
||||||
if (JKQTPIsOKFloat(xv) && JKQTPIsOKFloat(delta) ) {
|
|
||||||
|
|
||||||
if (start || xv+shift*delta+width*delta/2.0>maxx) maxx=xv+shift*delta+width*delta/2.0;
|
|
||||||
if (start || xv+shift*delta-width*delta/2.0<minx) minx=xv+shift*delta-width*delta/2.0;
|
|
||||||
double xvsgz;
|
|
||||||
xvsgz=xv+shift*delta+width*delta/2.0; SmallestGreaterZeroCompare_xvsgz();
|
|
||||||
xvsgz=xv+shift*delta-width*delta/2.0; SmallestGreaterZeroCompare_xvsgz();
|
|
||||||
start=false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JKQTPBarVerticalGraph::getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) {
|
bool JKQTPBarVerticalGraph::getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) {
|
||||||
miny=0;
|
return getValuesMinMax(miny, maxy, smallestGreaterZero);
|
||||||
maxy=0;
|
|
||||||
smallestGreaterZero=0;
|
|
||||||
if (baseline>0) {
|
|
||||||
smallestGreaterZero=baseline;
|
|
||||||
miny=baseline;
|
|
||||||
maxy=baseline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent==nullptr) return false;
|
int JKQTPBarVerticalGraph::getBarPositionColumn() const
|
||||||
|
|
||||||
JKQTPDatastore* datastore=parent->getDatastore();
|
|
||||||
int imin=0;
|
|
||||||
int imax=static_cast<int>(qMin(datastore->getRows(static_cast<size_t>(xColumn)), datastore->getRows(static_cast<size_t>(yColumn))));
|
|
||||||
if (imax<imin) {
|
|
||||||
int h=imin;
|
|
||||||
imin=imax;
|
|
||||||
imax=h;
|
|
||||||
}
|
|
||||||
if (imin<0) imin=0;
|
|
||||||
if (imax<0) imax=0;
|
|
||||||
|
|
||||||
for (int i=imin; i<imax; i++) {
|
|
||||||
double stack=0;
|
|
||||||
double yv=baseline;
|
|
||||||
if (!isHorizontal()) {
|
|
||||||
stack=getParentStackedMax(i);
|
|
||||||
yv=stack;
|
|
||||||
}
|
|
||||||
if (JKQTPIsOKFloat(yv)) {
|
|
||||||
if (yv>maxy) maxy=yv;
|
|
||||||
if (yv<miny) miny=yv;
|
|
||||||
double xvsgz;
|
|
||||||
xvsgz=yv; SmallestGreaterZeroCompare_xvsgz();
|
|
||||||
}
|
|
||||||
yv=stack+datastore->get(static_cast<size_t>(yColumn),static_cast<size_t>(i));
|
|
||||||
if (JKQTPIsOKFloat(yv)) {
|
|
||||||
if (yv>maxy) maxy=yv;
|
|
||||||
if (yv<miny) miny=yv;
|
|
||||||
double xvsgz;
|
|
||||||
xvsgz=yv; SmallestGreaterZeroCompare_xvsgz();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPBarVerticalGraph::autoscaleBarWidthAndShift(double maxWidth, double shrinkFactor)
|
|
||||||
{
|
{
|
||||||
if (parent) {
|
return xColumn;
|
||||||
double cntH=0;
|
|
||||||
for (size_t i=0; i<parent->getGraphCount(); i++) {
|
|
||||||
JKQTPPlotElement* g=parent->getGraph(i);
|
|
||||||
JKQTPBarVerticalGraph* gb=qobject_cast<JKQTPBarVerticalGraph*>(g);
|
|
||||||
if (gb && gb->isHorizontal()==isHorizontal()) {
|
|
||||||
cntH++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int JKQTPBarVerticalGraph::getBarHeightColumn() const
|
||||||
|
{
|
||||||
|
return yColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
double widthH=1.0/cntH*maxWidth*shrinkFactor;
|
void JKQTPBarVerticalGraph::setBarPositionColumn(int column)
|
||||||
double dH=maxWidth/(cntH);
|
{
|
||||||
double h=0.1+dH/2.0;
|
xColumn=column;
|
||||||
for (size_t i=0; i<parent->getGraphCount(); i++) {
|
|
||||||
JKQTPPlotElement* g=parent->getGraph(i);
|
|
||||||
JKQTPBarVerticalGraph* gb=qobject_cast<JKQTPBarVerticalGraph*>(g);
|
|
||||||
if (gb && gb->isHorizontal()==isHorizontal()) {
|
|
||||||
if (cntH>1) {
|
|
||||||
gb->width=widthH;
|
|
||||||
gb->shift=h-0.5;
|
|
||||||
h=h+dH;
|
|
||||||
} else {
|
|
||||||
gb->width=maxWidth;
|
|
||||||
gb->shift=0.0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
void JKQTPBarVerticalGraph::setBarPositionColumn(size_t column)
|
||||||
}
|
{
|
||||||
|
xColumn=column;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JKQTPBarVerticalGraph::autoscaleBarWidthAndShiftSeparatedGroups(double groupWidth) {
|
void JKQTPBarVerticalGraph::setBarHeightColumn(int column)
|
||||||
autoscaleBarWidthAndShift(groupWidth, 1);
|
{
|
||||||
|
yColumn=column;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarVerticalGraph::setBarHeightColumn(size_t column)
|
||||||
|
{
|
||||||
|
yColumn=column;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JKQTPBarVerticalGraph::considerForAutoscaling(JKQTPBarGraphBase *other) const
|
||||||
|
{
|
||||||
|
return (dynamic_cast<JKQTPBarVerticalGraph*>(other)!=nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -303,7 +188,7 @@ void JKQTPBarVerticalGraph::autoscaleBarWidthAndShiftSeparatedGroups(double grou
|
|||||||
|
|
||||||
|
|
||||||
JKQTPBarHorizontalGraph::JKQTPBarHorizontalGraph(JKQTBasePlotter *parent):
|
JKQTPBarHorizontalGraph::JKQTPBarHorizontalGraph(JKQTBasePlotter *parent):
|
||||||
JKQTPBarVerticalGraph(parent)
|
JKQTPBarGraphBase(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -314,6 +199,41 @@ JKQTPBarHorizontalGraph::JKQTPBarHorizontalGraph(JKQTPlotter *parent):
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int JKQTPBarHorizontalGraph::getBarPositionColumn() const
|
||||||
|
{
|
||||||
|
return yColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
int JKQTPBarHorizontalGraph::getBarHeightColumn() const
|
||||||
|
{
|
||||||
|
return xColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarHorizontalGraph::setBarPositionColumn(int column)
|
||||||
|
{
|
||||||
|
yColumn=column;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarHorizontalGraph::setBarPositionColumn(size_t column)
|
||||||
|
{
|
||||||
|
yColumn=column;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarHorizontalGraph::setBarHeightColumn(int column)
|
||||||
|
{
|
||||||
|
xColumn=column;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarHorizontalGraph::setBarHeightColumn(size_t column)
|
||||||
|
{
|
||||||
|
xColumn=column;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JKQTPBarHorizontalGraph::considerForAutoscaling(JKQTPBarGraphBase *other) const
|
||||||
|
{
|
||||||
|
return (dynamic_cast<JKQTPBarHorizontalGraph*>(other)!=nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void JKQTPBarHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
|
void JKQTPBarHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||||
#ifdef JKQTBP_AUTOTIMER
|
#ifdef JKQTBP_AUTOTIMER
|
||||||
JKQTPAutoOutputTimer jkaaot("JKQTPBarVerticalGraph::draw");
|
JKQTPAutoOutputTimer jkaaot("JKQTPBarVerticalGraph::draw");
|
||||||
@ -401,180 +321,18 @@ void JKQTPBarHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool JKQTPBarHorizontalGraph::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) {
|
bool JKQTPBarHorizontalGraph::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) {
|
||||||
minx=0;
|
return getValuesMinMax(minx, maxx, smallestGreaterZero);
|
||||||
maxx=0;
|
|
||||||
smallestGreaterZero=0;
|
|
||||||
if (baseline>0) {
|
|
||||||
smallestGreaterZero=baseline;
|
|
||||||
minx=baseline;
|
|
||||||
maxx=baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parent==nullptr) return false;
|
|
||||||
|
|
||||||
JKQTPDatastore* datastore=parent->getDatastore();
|
|
||||||
int imin=0;
|
|
||||||
int imax=static_cast<int>(qMin(datastore->getRows(static_cast<size_t>(xColumn)), datastore->getRows(static_cast<size_t>(yColumn))));
|
|
||||||
if (imax<imin) {
|
|
||||||
int h=imin;
|
|
||||||
imin=imax;
|
|
||||||
imax=h;
|
|
||||||
}
|
|
||||||
if (imin<0) imin=0;
|
|
||||||
if (imax<0) imax=0;
|
|
||||||
|
|
||||||
for (int i=imin; i<imax; i++) {
|
|
||||||
double stack=0;
|
|
||||||
double xv=baseline;
|
|
||||||
if (isHorizontal()) {
|
|
||||||
stack=getParentStackedMax(i);
|
|
||||||
xv=stack;
|
|
||||||
}
|
|
||||||
if (JKQTPIsOKFloat(xv)) {
|
|
||||||
if (xv>maxx) maxx=xv;
|
|
||||||
if (xv<minx) minx=xv;
|
|
||||||
double xvsgz;
|
|
||||||
xvsgz=xv; SmallestGreaterZeroCompare_xvsgz();
|
|
||||||
}
|
|
||||||
xv=stack+datastore->get(static_cast<size_t>(xColumn),static_cast<size_t>(i));
|
|
||||||
if (JKQTPIsOKFloat(xv)) {
|
|
||||||
if (xv>maxx) maxx=xv;
|
|
||||||
if (xv<minx) minx=xv;
|
|
||||||
double xvsgz;
|
|
||||||
xvsgz=xv; SmallestGreaterZeroCompare_xvsgz();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JKQTPBarHorizontalGraph::getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) {
|
bool JKQTPBarHorizontalGraph::getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) {
|
||||||
bool start=true;
|
return getPositionsMinMax(miny, maxy, smallestGreaterZero);
|
||||||
miny=0;
|
|
||||||
maxy=0;
|
|
||||||
smallestGreaterZero=0;
|
|
||||||
|
|
||||||
if (parent==nullptr) return false;
|
|
||||||
|
|
||||||
JKQTPDatastore* datastore=parent->getDatastore();
|
|
||||||
int imin=0;
|
|
||||||
int imax=static_cast<int>(qMin(datastore->getRows(static_cast<size_t>(xColumn)), datastore->getRows(static_cast<size_t>(yColumn))));
|
|
||||||
if (imax<imin) {
|
|
||||||
int h=imin;
|
|
||||||
imin=imax;
|
|
||||||
imax=h;
|
|
||||||
}
|
|
||||||
if (imin<0) imin=0;
|
|
||||||
if (imax<0) imax=0;
|
|
||||||
|
|
||||||
for (int i=imin; i<imax; i++) {
|
|
||||||
double yv=datastore->get(static_cast<size_t>(yColumn),static_cast<size_t>(i));
|
|
||||||
double delta, deltap, deltam;
|
|
||||||
int sr=datastore->getNextLowerIndex(yColumn, i);
|
|
||||||
int lr=datastore->getNextHigherIndex(yColumn, i);
|
|
||||||
|
|
||||||
if (sr<0 && lr<0) { // only one y-value
|
|
||||||
deltam=0.5;
|
|
||||||
deltap=0.5;
|
|
||||||
} else if (lr<0) { // the right-most y-value
|
|
||||||
deltap=deltam=fabs(yv-datastore->get(yColumn,sr))/2.0;
|
|
||||||
} else if (sr<0) { // the left-most y-value
|
|
||||||
deltam=deltap=fabs(datastore->get(yColumn,lr)-yv)/2.0;
|
|
||||||
} else {
|
|
||||||
deltam=fabs(yv-datastore->get(yColumn,sr))/2.0;
|
|
||||||
deltap=fabs(datastore->get(yColumn,lr)-yv)/2.0;
|
|
||||||
}
|
|
||||||
delta=deltap+deltam;
|
|
||||||
if (JKQTPIsOKFloat(yv) && JKQTPIsOKFloat(delta) ) {
|
|
||||||
|
|
||||||
if (start || yv+shift*delta+width*delta/2.0>maxy) maxy=yv+shift*delta+width*delta/2.0;
|
|
||||||
if (start || yv+shift*delta-width*delta/2.0<miny) miny=yv+shift*delta-width*delta/2.0;
|
|
||||||
double xvsgz;
|
|
||||||
xvsgz=yv+shift*delta+width*delta/2.0; SmallestGreaterZeroCompare_xvsgz();
|
|
||||||
xvsgz=yv+shift*delta-width*delta/2.0; SmallestGreaterZeroCompare_xvsgz();
|
|
||||||
start=false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return !start;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JKQTPBarHorizontalGraph::isHorizontal() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double JKQTPBarVerticalGraph::getParentStackedMax(int /*index*/) const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JKQTPBarVerticalGraph::hasStackParent() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
double JKQTPBarVerticalGraph::getStackedMax(int /*index*/) const
|
|
||||||
{
|
|
||||||
return baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool JKQTPBarVerticalGraph::isHorizontal() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPBarVerticalGraph::setColor(QColor c)
|
|
||||||
{
|
|
||||||
setLineColor(c);
|
|
||||||
setFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphFillColorDerivationMode, c));
|
|
||||||
c.setAlphaF(0.5);
|
|
||||||
setHighlightingLineColor(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPBarVerticalGraph::setShift(double __value)
|
|
||||||
{
|
|
||||||
this->shift = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
double JKQTPBarVerticalGraph::getShift() const
|
|
||||||
{
|
|
||||||
return this->shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPBarVerticalGraph::setWidth(double __value)
|
|
||||||
{
|
|
||||||
this->width = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
double JKQTPBarVerticalGraph::getWidth() const
|
|
||||||
{
|
|
||||||
return this->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPBarVerticalGraph::setBaseline(double __value)
|
|
||||||
{
|
|
||||||
this->baseline = __value;
|
|
||||||
}
|
|
||||||
|
|
||||||
double JKQTPBarVerticalGraph::getBaseline() const
|
|
||||||
{
|
|
||||||
return this->baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JKQTPBarVerticalGraph::setFillColor_and_darkenedColor(QColor fill, int colorDarker)
|
|
||||||
{
|
|
||||||
setFillColor(fill);
|
|
||||||
setLineColor(fill.darker(colorDarker));
|
|
||||||
}
|
|
||||||
|
|
||||||
JKQTPBarHorizontalErrorGraph::JKQTPBarHorizontalErrorGraph(JKQTBasePlotter *parent):
|
JKQTPBarHorizontalErrorGraph::JKQTPBarHorizontalErrorGraph(JKQTBasePlotter *parent):
|
||||||
JKQTPBarHorizontalGraph(parent)
|
JKQTPBarHorizontalGraph(parent)
|
||||||
{
|
{
|
||||||
@ -641,6 +399,38 @@ void JKQTPBarHorizontalErrorGraph::drawErrorsAfter(JKQTPEnhancedPainter &painter
|
|||||||
else plotErrorIndicators(painter, parent, this, xColumn, yColumn, 0.0, shift, &sortedIndices);
|
else plotErrorIndicators(painter, parent, this, xColumn, yColumn, 0.0, shift, &sortedIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int JKQTPBarHorizontalErrorGraph::getBarErrorColumn() const
|
||||||
|
{
|
||||||
|
return getXErrorColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
int JKQTPBarHorizontalErrorGraph::getBarLowerErrorColumn() const
|
||||||
|
{
|
||||||
|
return getXErrorColumnLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarHorizontalErrorGraph::setBarErrorColumn(int column)
|
||||||
|
{
|
||||||
|
setXErrorColumn(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarHorizontalErrorGraph::setBarErrorColumn(size_t column)
|
||||||
|
{
|
||||||
|
setXErrorColumn(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarHorizontalErrorGraph::setBarLowerErrorColumn(int column)
|
||||||
|
{
|
||||||
|
setXErrorColumnLower(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarHorizontalErrorGraph::setBarLowerErrorColumn(size_t column)
|
||||||
|
{
|
||||||
|
setXErrorColumnLower(column);
|
||||||
|
}
|
||||||
|
|
||||||
JKQTPBarVerticalErrorGraph::JKQTPBarVerticalErrorGraph(JKQTBasePlotter *parent):
|
JKQTPBarVerticalErrorGraph::JKQTPBarVerticalErrorGraph(JKQTBasePlotter *parent):
|
||||||
JKQTPBarVerticalGraph(parent)
|
JKQTPBarVerticalGraph(parent)
|
||||||
{
|
{
|
||||||
@ -745,6 +535,36 @@ bool JKQTPBarVerticalErrorGraph::getYMinMax(double &miny, double &maxy, double &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int JKQTPBarVerticalErrorGraph::getBarErrorColumn() const
|
||||||
|
{
|
||||||
|
return getYErrorColumn();
|
||||||
|
}
|
||||||
|
|
||||||
|
int JKQTPBarVerticalErrorGraph::getBarLowerErrorColumn() const
|
||||||
|
{
|
||||||
|
return getYErrorColumnLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarVerticalErrorGraph::setBarErrorColumn(int column)
|
||||||
|
{
|
||||||
|
setYErrorColumn(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarVerticalErrorGraph::setBarErrorColumn(size_t column)
|
||||||
|
{
|
||||||
|
setYErrorColumn(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarVerticalErrorGraph::setBarLowerErrorColumn(int column)
|
||||||
|
{
|
||||||
|
setYErrorColumnLower(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarVerticalErrorGraph::setBarLowerErrorColumn(size_t column)
|
||||||
|
{
|
||||||
|
setYErrorColumnLower(column);
|
||||||
|
}
|
||||||
|
|
||||||
void JKQTPBarVerticalErrorGraph::drawErrorsAfter(JKQTPEnhancedPainter &painter)
|
void JKQTPBarVerticalErrorGraph::drawErrorsAfter(JKQTPEnhancedPainter &painter)
|
||||||
{
|
{
|
||||||
//plotErrorIndicators(painter, parent, this, xColumn, yColumn, shift, 0.0);
|
//plotErrorIndicators(painter, parent, this, xColumn, yColumn, shift, 0.0);
|
||||||
@ -752,6 +572,17 @@ void JKQTPBarVerticalErrorGraph::drawErrorsAfter(JKQTPEnhancedPainter &painter)
|
|||||||
else plotErrorIndicators(painter, parent, this, xColumn, yColumn, shift, 0, &sortedIndices);
|
else plotErrorIndicators(painter, parent, this, xColumn, yColumn, shift, 0, &sortedIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
JKQTPBarVerticalStackableGraph::JKQTPBarVerticalStackableGraph(JKQTBasePlotter *parent):
|
JKQTPBarVerticalStackableGraph::JKQTPBarVerticalStackableGraph(JKQTBasePlotter *parent):
|
||||||
JKQTPBarVerticalGraph(parent), stackParent(nullptr)
|
JKQTPBarVerticalGraph(parent), stackParent(nullptr)
|
||||||
{
|
{
|
||||||
@ -779,7 +610,7 @@ double JKQTPBarVerticalStackableGraph::getParentStackedMax(int index) const
|
|||||||
if (stackParent) {
|
if (stackParent) {
|
||||||
return stackParent->getStackedMax(index);
|
return stackParent->getStackedMax(index);
|
||||||
} else {
|
} else {
|
||||||
return 0.0;
|
return baseline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,7 +624,10 @@ const JKQTPBarVerticalStackableGraph *JKQTPBarVerticalStackableGraph::getStackPa
|
|||||||
return stackParent;
|
return stackParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JKQTPBarVerticalStackableGraph *JKQTPBarVerticalStackableGraph::getStackParent()
|
||||||
|
{
|
||||||
|
return stackParent;
|
||||||
|
}
|
||||||
|
|
||||||
double JKQTPBarVerticalStackableGraph::getStackedMax(int index) const
|
double JKQTPBarVerticalStackableGraph::getStackedMax(int index) const
|
||||||
{
|
{
|
||||||
@ -836,6 +670,11 @@ const JKQTPBarHorizontalStackableGraph *JKQTPBarHorizontalStackableGraph::getSta
|
|||||||
return stackParent;
|
return stackParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JKQTPBarHorizontalStackableGraph *JKQTPBarHorizontalStackableGraph::getStackParent()
|
||||||
|
{
|
||||||
|
return stackParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
double JKQTPBarHorizontalStackableGraph::getStackedMax(int index) const
|
double JKQTPBarHorizontalStackableGraph::getStackedMax(int index) const
|
||||||
{
|
{
|
||||||
@ -856,7 +695,7 @@ double JKQTPBarHorizontalStackableGraph::getParentStackedMax(int index) const
|
|||||||
if (stackParent) {
|
if (stackParent) {
|
||||||
return stackParent->getStackedMax(index);
|
return stackParent->getStackedMax(index);
|
||||||
} else {
|
} else {
|
||||||
return 0.0;
|
return baseline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,12 +26,13 @@
|
|||||||
#include "jkqtplotter/jkqtpgraphsbase.h"
|
#include "jkqtplotter/jkqtpgraphsbase.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbaseerrors.h"
|
#include "jkqtplotter/jkqtpgraphsbaseerrors.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
||||||
|
#include "jkqtplotter/graphs/jkqtpbarchartbase.h"
|
||||||
#ifndef jkqtpgraphsbarchart_H
|
#ifndef jkqtpgraphsbarchart_H
|
||||||
#define jkqtpgraphsbarchart_H
|
#define jkqtpgraphsbarchart_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief This implements a bar graph with bars starting at \f$ y=0 \f$ to \f$ y=f(x) \f$
|
/*! \brief This implements a bar graph with bars starting at \f$ yoverride \f$ to \f$ y=f(x) \f$
|
||||||
\ingroup jkqtplotter_barssticks
|
\ingroup jkqtplotter_barssticks
|
||||||
|
|
||||||
This class plots a bargraph. This image explains the parameters:
|
This class plots a bargraph. This image explains the parameters:
|
||||||
@ -43,7 +44,7 @@
|
|||||||
to plot multiple bars for every x-value, by having on JKQTPSpecialLineHorizontalGraph object per
|
to plot multiple bars for every x-value, by having on JKQTPSpecialLineHorizontalGraph object per
|
||||||
set of bars that belong together. For example for three bars per x-value one would set:
|
set of bars that belong together. For example for three bars per x-value one would set:
|
||||||
\verbatim
|
\verbatim
|
||||||
width=0.3
|
widthoverride.3
|
||||||
shift=-0.3 / 0 / +0.3
|
shift=-0.3 / 0 / +0.3
|
||||||
\endverbatim
|
\endverbatim
|
||||||
This results in a bargraph, as shown here:
|
This results in a bargraph, as shown here:
|
||||||
@ -56,7 +57,7 @@
|
|||||||
|
|
||||||
\see JKQTPBarHorizontalGraph, \ref JKQTPlotterBarcharts, jkqtpstatAddHHistogram1D(), jkqtpstatAddHHistogram1DAutoranged()
|
\see JKQTPBarHorizontalGraph, \ref JKQTPlotterBarcharts, jkqtpstatAddHHistogram1D(), jkqtpstatAddHHistogram1DAutoranged()
|
||||||
*/
|
*/
|
||||||
class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalGraph: public JKQTPXYGraph, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
|
class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalGraph: public JKQTPBarGraphBase {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
/** \brief class constructor */
|
/** \brief class constructor */
|
||||||
@ -66,10 +67,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalGraph: public JKQTPXYGraph, public
|
|||||||
|
|
||||||
/** \brief plots the graph to the plotter object specified as parent */
|
/** \brief plots the graph to the plotter object specified as parent */
|
||||||
virtual void draw(JKQTPEnhancedPainter& painter) override;
|
virtual void draw(JKQTPEnhancedPainter& painter) override;
|
||||||
/** \brief plots a key marker inside the specified rectangle \a rect */
|
|
||||||
virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) override;
|
|
||||||
/** \brief returns the color to be used for the key label */
|
|
||||||
virtual QColor getKeyLabelColor() const override;
|
|
||||||
|
|
||||||
/** \brief get the maximum and minimum x-value of the graph
|
/** \brief get the maximum and minimum x-value of the graph
|
||||||
*
|
*
|
||||||
@ -82,131 +79,34 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalGraph: public JKQTPXYGraph, public
|
|||||||
*/
|
*/
|
||||||
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
||||||
|
|
||||||
/** \brief finds all bar charts of the same orientation and determines width and shift, so they stand side by side
|
/** \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;
|
||||||
* \param maxWidth the maximum (relative) width, that all bars will span of the (doubled) inter-bar distance
|
|
||||||
* \param shrinkFactor factor, by which the bar are shrinked compared to the available space
|
|
||||||
*
|
|
||||||
* \note This function will scale ALL graphs of the parent plot, which were derived from JKQTPBarHorizontalGraph, that match in orientation (as returned by isHorizontal() ).
|
|
||||||
*/
|
|
||||||
virtual void autoscaleBarWidthAndShift(double maxWidth=0.9, double shrinkFactor=0.8);
|
|
||||||
|
|
||||||
/** \brief equivalent to \c autoscaleBarWidthAndShift(groupWidth,1);
|
/** \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;
|
||||||
void autoscaleBarWidthAndShiftSeparatedGroups(double groupWidth=0.75);
|
|
||||||
|
|
||||||
/** \brief retruns \c true, if the bars are horizontal (JKQTPBarHorizontalGraph) and \c false if they are vertical (JKQTPBarVerticalGraph) */
|
public slots:
|
||||||
virtual bool isHorizontal() const;
|
/** \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 set outline and fill color at the same time
|
/** \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 */
|
||||||
* \see setFillColor_and_darkenedColor()
|
virtual void setBarPositionColumn(size_t column) override;
|
||||||
*/
|
|
||||||
virtual void setColor(QColor c);
|
|
||||||
|
|
||||||
/*! \copydoc shift */
|
/** \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 */
|
||||||
void setShift(double __value);
|
virtual void setBarHeightColumn(int column) override;
|
||||||
/*! \copydoc shift */
|
|
||||||
double getShift() const;
|
|
||||||
/*! \copydoc width */
|
|
||||||
void setWidth(double __value);
|
|
||||||
/*! \copydoc width */
|
|
||||||
double getWidth() const;
|
|
||||||
/*! \copydoc baseline */
|
|
||||||
void setBaseline(double __value);
|
|
||||||
/*! \copydoc baseline */
|
|
||||||
double getBaseline() const;
|
|
||||||
/** \brief sets the fill color and the color together, where fillColor is set to \a fill and the line-color is set to \c fill.darker(colorDarker)
|
|
||||||
* \see setColor()
|
|
||||||
*/
|
|
||||||
void setFillColor_and_darkenedColor(QColor fill, int colorDarker=200);
|
|
||||||
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:
|
|
||||||
* \image html bargraph_basics.png
|
|
||||||
*/
|
|
||||||
double width;
|
|
||||||
/** \brief the shift of the bargraphs, relative to the distance between the current and the next x-value
|
|
||||||
*
|
|
||||||
* See the following graphic to understand this concept:
|
|
||||||
* \image html bargraph_basics.png
|
|
||||||
*/
|
|
||||||
double shift;
|
|
||||||
|
|
||||||
/** \brief baseline of the plot (NOTE: 0 is interpreted as until plot border in log-mode!!!)
|
/** \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;
|
||||||
double baseline;
|
|
||||||
|
|
||||||
|
|
||||||
/** \brief used to generate stacked plots: returns the upper boundary of this plot in a stack, for the index-th datapoint
|
|
||||||
*
|
|
||||||
* \note This function returns \a baseline in this implementation. It is implemented in the derived classes JKQTPBarVerticalStackableGraph
|
|
||||||
* and JKQTPBarHorizontalStackableGraph. The function is placed here, so the plotting does not have to be reimplemented in the
|
|
||||||
* derived classes that allow for stacking, but can be implemented once centrally.
|
|
||||||
*/
|
|
||||||
virtual double getStackedMax(int index) const;
|
|
||||||
|
|
||||||
/** \brief calls getStackedMax() on the stack parent (if available)
|
|
||||||
*
|
|
||||||
* \note This function returns \c 0.0 in this implementation. It is implemented in the derived classes JKQTPBarVerticalStackableGraph
|
|
||||||
* and JKQTPBarHorizontalStackableGraph. The function is placed here, so the plotting does not have to be reimplemented in the
|
|
||||||
* derived classes that allow for stacking, but can be implemented once centrally.
|
|
||||||
*/
|
|
||||||
virtual double getParentStackedMax(int index) const;
|
|
||||||
|
|
||||||
/** \brief returns \c true, if a stack parent is set (if available)
|
|
||||||
*
|
|
||||||
* \note This function returns \c false in this implementation. It is implemented in the derived classes JKQTPBarVerticalStackableGraph
|
|
||||||
* and JKQTPBarHorizontalStackableGraph. The function is placed here, so the plotting does not have to be reimplemented in the
|
|
||||||
* derived classes that allow for stacking, but can be implemented once centrally.
|
|
||||||
*/
|
|
||||||
virtual bool hasStackParent() const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief This implements a bar graph with bars starting at \f$ y=0 \f$ to \f$ y=f(x) \f$
|
|
||||||
* Optionally several graphs of this type may be stacked on top of each other
|
|
||||||
* \ingroup jkqtplotter_barssticks
|
|
||||||
*
|
|
||||||
* Draw stacked barcharts by connecting several plots by calling \c setStackedParent(belowPlot) for each plot
|
|
||||||
* \image html JKQTPBarVerticalGraphStacked.png
|
|
||||||
*
|
|
||||||
* \see JKQTPBarVerticalGraph, \ref JKQTPlotterStackedBarChart
|
|
||||||
*/
|
|
||||||
class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalStackableGraph: public JKQTPBarVerticalGraph {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
/** \brief class constructor */
|
|
||||||
JKQTPBarVerticalStackableGraph(JKQTBasePlotter* parent=nullptr);
|
|
||||||
/** \brief class constructor */
|
|
||||||
JKQTPBarVerticalStackableGraph(JKQTPlotter* parent);
|
|
||||||
/** \brief stacks this barchart upon the given \a parentGraph */
|
|
||||||
void stackUpon(JKQTPBarVerticalStackableGraph* parentGraph);
|
|
||||||
/** \brief unstacks this graph (i.e. deletes the parent graph in the stack) */
|
|
||||||
void dontStackUpon();
|
|
||||||
/** \brief returns the stack parent graph, or \c nullptr */
|
|
||||||
const JKQTPBarVerticalStackableGraph* getStackParent() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** \brief if set (!=nullptr), the current plot is drawn stacked onto this plot
|
/** \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) */
|
||||||
* draw stacked barcharts by connecting several plots by calling \c setStackedParent(belowPlot) for each plot
|
virtual bool considerForAutoscaling( JKQTPBarGraphBase* other) const override;
|
||||||
*/
|
|
||||||
JKQTPBarVerticalStackableGraph* stackParent;
|
|
||||||
|
|
||||||
/** \brief used to generate stacked plots: returns the upper boundary of this plot in a stack, for the index-th datapoint */
|
|
||||||
virtual double getStackedMax(int index) const override;
|
|
||||||
/** \brief calls getStackedMax() on the stack parent (if available), or \c 0.0 */
|
|
||||||
virtual double getParentStackedMax(int index) const override;
|
|
||||||
|
|
||||||
/** \brief returns \c true, if a stack parent is set (if available) */
|
|
||||||
virtual bool hasStackParent() const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief This implements a bar graph with bars starting at \f$ y=0 \f$ to \f$ y=f(x) \f$
|
/*! \brief This implements a bar graph with bars starting at \f$ yoverride \f$ to \f$ y=f(x) \f$
|
||||||
* and error indicator
|
* and error indicator
|
||||||
* \ingroup jkqtplotter_barssticks
|
* \ingroup jkqtplotter_barssticks
|
||||||
*
|
*
|
||||||
@ -231,6 +131,22 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalErrorGraph: public JKQTPBarVertical
|
|||||||
*/
|
*/
|
||||||
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
||||||
|
|
||||||
|
/** \brief returns the column that contains the bar height errors */
|
||||||
|
int getBarErrorColumn() const;
|
||||||
|
/** \brief returns the column that contains the lower bar height errors */
|
||||||
|
int getBarLowerErrorColumn() const;
|
||||||
|
public slots:
|
||||||
|
/** \brief sets the column that contains the bar height errors */
|
||||||
|
void setBarErrorColumn(int column) ;
|
||||||
|
|
||||||
|
/** \brief sets the column that contains the bar height errors */
|
||||||
|
void setBarErrorColumn(size_t column) ;
|
||||||
|
/** \brief sets the column that contains the bar height errors */
|
||||||
|
void setBarLowerErrorColumn(int column) ;
|
||||||
|
|
||||||
|
/** \brief sets the column that contains the bar height errors */
|
||||||
|
void setBarLowerErrorColumn(size_t column) ;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** \brief this function is used to plot error inidcators before plotting the graphs. */
|
/** \brief this function is used to plot error inidcators before plotting the graphs. */
|
||||||
virtual void drawErrorsAfter(JKQTPEnhancedPainter& painter) override;
|
virtual void drawErrorsAfter(JKQTPEnhancedPainter& painter) override;
|
||||||
@ -239,7 +155,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalErrorGraph: public JKQTPBarVertical
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief This implements a bar graph with bars starting at \f$ x=0 \f$ to \f$ x=f(y) \f$
|
|
||||||
|
/*! \brief This implements a bar graph with bars starting at \f$ xoverride \f$ to \f$ x=f(y) \f$
|
||||||
\ingroup jkqtplotter_barssticks
|
\ingroup jkqtplotter_barssticks
|
||||||
|
|
||||||
This works much the same as JKQTPBarHorizontalGraph. Here is an example output:
|
This works much the same as JKQTPBarHorizontalGraph. Here is an example output:
|
||||||
@ -249,7 +166,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalErrorGraph: public JKQTPBarVertical
|
|||||||
|
|
||||||
\see \ref JKQTPlotterBarcharts, jkqtpstatAddVHistogram1D(), jkqtpstatAddVHistogram1DAutoranged()
|
\see \ref JKQTPlotterBarcharts, jkqtpstatAddVHistogram1D(), jkqtpstatAddVHistogram1DAutoranged()
|
||||||
*/
|
*/
|
||||||
class JKQTPLOTTER_LIB_EXPORT JKQTPBarHorizontalGraph: public JKQTPBarVerticalGraph {
|
class JKQTPLOTTER_LIB_EXPORT JKQTPBarHorizontalGraph: public JKQTPBarGraphBase {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
/** \brief class constructor */
|
/** \brief class constructor */
|
||||||
@ -271,54 +188,34 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarHorizontalGraph: public JKQTPBarVerticalGra
|
|||||||
*/
|
*/
|
||||||
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
||||||
|
|
||||||
virtual bool isHorizontal() const 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 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 This implements a bar graph with bars starting at \f$ y=0 \f$ to \f$ y=f(x) \f$
|
/** \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 */
|
||||||
* Optionally several graphs of this type may be stacked on top of each other
|
virtual void setBarHeightColumn(int column) override;
|
||||||
* \ingroup jkqtplotter_barssticks
|
|
||||||
*
|
|
||||||
* Draw stacked barcharts by connecting several plots by calling \c setStackedParent(belowPlot) for each plot
|
|
||||||
* \image html JKQTPBarHorizontalGraphStacked.png
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* \see JKQTPBarHorizontalGraph, \ref JKQTPlotterStackedBarChart
|
|
||||||
*/
|
|
||||||
class JKQTPLOTTER_LIB_EXPORT JKQTPBarHorizontalStackableGraph: public JKQTPBarHorizontalGraph {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
/** \brief class constructor */
|
|
||||||
JKQTPBarHorizontalStackableGraph(JKQTBasePlotter* parent=nullptr);
|
|
||||||
/** \brief class constructor */
|
|
||||||
JKQTPBarHorizontalStackableGraph(JKQTPlotter* parent);
|
|
||||||
/** \brief stacks this barchart upon the given \a parentGraph */
|
|
||||||
void stackUpon(JKQTPBarHorizontalStackableGraph* parentGraph);
|
|
||||||
/** \brief unstacks this graph (i.e. deletes the parent graph in the stack) */
|
|
||||||
void dontStackUpon();
|
|
||||||
/** \brief returns the stack parent graph, or \c nullptr */
|
|
||||||
const JKQTPBarHorizontalStackableGraph* getStackParent() const;
|
|
||||||
|
|
||||||
|
/** \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:
|
protected:
|
||||||
|
|
||||||
/** \brief if set (!=nullptr), the current plot is drawn stacked onto this plot
|
/** \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) */
|
||||||
* draw stacked barcharts by connecting several plots by calling \c setStackedParent(belowPlot) for each plot
|
virtual bool considerForAutoscaling( JKQTPBarGraphBase* other) const override;
|
||||||
*/
|
|
||||||
JKQTPBarHorizontalStackableGraph* stackParent;
|
|
||||||
|
|
||||||
/** \brief used to generate stacked plots: returns the upper boundary of this plot in a stack, for the index-th datapoint */
|
|
||||||
virtual double getStackedMax(int index) const override;
|
|
||||||
/** \brief calls getStackedMax() on the stack parent (if available), or \c 0.0 */
|
|
||||||
virtual double getParentStackedMax(int index) const override;
|
|
||||||
|
|
||||||
/** \brief returns \c true, if a stack parent is set (if available) */
|
|
||||||
virtual bool hasStackParent() const override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief This implements a bar graph with bars starting at \f$ x=0 \f$ to \f$ x=f(y) \f$
|
|
||||||
|
|
||||||
|
/*! \brief This implements a bar graph with bars starting at \f$ xoverride \f$ to \f$ x=f(y) \f$
|
||||||
* and error indicator
|
* and error indicator
|
||||||
* \ingroup jkqtplotter_barssticks
|
* \ingroup jkqtplotter_barssticks
|
||||||
*
|
*
|
||||||
@ -344,6 +241,22 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarHorizontalErrorGraph: public JKQTPBarHorizo
|
|||||||
*/
|
*/
|
||||||
virtual bool getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) override;
|
virtual bool getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) override;
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief returns the column that contains the bar height errors */
|
||||||
|
int getBarErrorColumn() const;
|
||||||
|
/** \brief returns the column that contains the lower bar height errors */
|
||||||
|
int getBarLowerErrorColumn() const;
|
||||||
|
public slots:
|
||||||
|
/** \brief sets the column that contains the bar height errors */
|
||||||
|
void setBarErrorColumn(int column) ;
|
||||||
|
|
||||||
|
/** \brief sets the column that contains the bar height errors */
|
||||||
|
void setBarErrorColumn(size_t column) ;
|
||||||
|
/** \brief sets the column that contains the bar height errors */
|
||||||
|
void setBarLowerErrorColumn(int column) ;
|
||||||
|
|
||||||
|
/** \brief sets the column that contains the bar height errors */
|
||||||
|
void setBarLowerErrorColumn(size_t column) ;
|
||||||
protected:
|
protected:
|
||||||
/** \brief this function is used to plot error inidcators before plotting the graphs. */
|
/** \brief this function is used to plot error inidcators before plotting the graphs. */
|
||||||
virtual void drawErrorsAfter(JKQTPEnhancedPainter& painter) override;
|
virtual void drawErrorsAfter(JKQTPEnhancedPainter& painter) override;
|
||||||
@ -355,4 +268,109 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBarHorizontalErrorGraph: public JKQTPBarHorizo
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief This implements a bar graph with bars starting at \f$ yoverride \f$ to \f$ y=f(x) \f$
|
||||||
|
* Optionally several graphs of this type may be stacked on top of each other
|
||||||
|
* \ingroup jkqtplotter_barssticks
|
||||||
|
*
|
||||||
|
* Draw stacked barcharts by connecting several plots by calling \c setStackedParent(belowPlot) for each plot
|
||||||
|
* \image html JKQTPBarVerticalGraphStacked.png
|
||||||
|
*
|
||||||
|
* \see JKQTPBarVerticalGraph, \ref JKQTPlotterStackedBarChart
|
||||||
|
*/
|
||||||
|
class JKQTPLOTTER_LIB_EXPORT JKQTPBarVerticalStackableGraph: public JKQTPBarVerticalGraph {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPBarVerticalStackableGraph(JKQTBasePlotter* parent=nullptr);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPBarVerticalStackableGraph(JKQTPlotter* parent);
|
||||||
|
/** \brief stacks this barchart upon the given \a parentGraph */
|
||||||
|
void stackUpon(JKQTPBarVerticalStackableGraph* parentGraph);
|
||||||
|
/** \brief unstacks this graph (i.e. deletes the parent graph in the stack) */
|
||||||
|
void dontStackUpon();
|
||||||
|
/** \brief returns the stack parent graph, or \c nullptr */
|
||||||
|
const JKQTPBarVerticalStackableGraph* getStackParent() const;
|
||||||
|
/** \brief returns the stack parent graph, or \c nullptr */
|
||||||
|
JKQTPBarVerticalStackableGraph* getStackParent();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/** \brief if set (!=nullptr), the current plot is drawn stacked onto this plot
|
||||||
|
*
|
||||||
|
* draw stacked barcharts by connecting several plots by calling \c setStackedParent(belowPlot) for each plot
|
||||||
|
*/
|
||||||
|
JKQTPBarVerticalStackableGraph* stackParent;
|
||||||
|
|
||||||
|
/** \brief used to generate stacked plots: returns the upper boundary of the parent plot in a stack, for the index-th datapoint */
|
||||||
|
double getParentStackedMax(int index) const ;
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief returns \c true, if a stack parent is set (if available) */
|
||||||
|
bool hasStackParent() const ;
|
||||||
|
/** \brief used to generate stacked plots: returns the upper boundary of this plot in a stack, for the index-th datapoint */
|
||||||
|
double getStackedMax(int index) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief This implements a bar graph with bars starting at \f$ yoverride \f$ to \f$ y=f(x) \f$
|
||||||
|
* Optionally several graphs of this type may be stacked on top of each other
|
||||||
|
* \ingroup jkqtplotter_barssticks
|
||||||
|
*
|
||||||
|
* Draw stacked barcharts by connecting several plots by calling \c setStackedParent(belowPlot) for each plot
|
||||||
|
* \image html JKQTPBarHorizontalGraphStacked.png
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \see JKQTPBarHorizontalGraph, \ref JKQTPlotterStackedBarChart
|
||||||
|
*/
|
||||||
|
class JKQTPLOTTER_LIB_EXPORT JKQTPBarHorizontalStackableGraph: public JKQTPBarHorizontalGraph {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPBarHorizontalStackableGraph(JKQTBasePlotter* parent=nullptr);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPBarHorizontalStackableGraph(JKQTPlotter* parent);
|
||||||
|
/** \brief stacks this barchart upon the given \a parentGraph */
|
||||||
|
void stackUpon(JKQTPBarHorizontalStackableGraph* parentGraph);
|
||||||
|
/** \brief unstacks this graph (i.e. deletes the parent graph in the stack) */
|
||||||
|
void dontStackUpon();
|
||||||
|
/** \brief returns the stack parent graph, or \c nullptr */
|
||||||
|
const JKQTPBarHorizontalStackableGraph* getStackParent() const;
|
||||||
|
/** \brief returns the stack parent graph, or \c nullptr */
|
||||||
|
JKQTPBarHorizontalStackableGraph* getStackParent() ;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/** \brief if set (!=nullptr), the current plot is drawn stacked onto this plot
|
||||||
|
*
|
||||||
|
* draw stacked barcharts by connecting several plots by calling \c setStackedParent(belowPlot) for each plot
|
||||||
|
*/
|
||||||
|
JKQTPBarHorizontalStackableGraph* stackParent;
|
||||||
|
|
||||||
|
/** \brief used to generate stacked plots: returns the upper boundary of the parent plot in a stack, for the index-th datapoint */
|
||||||
|
virtual double getParentStackedMax(int index) const override;
|
||||||
|
|
||||||
|
/** \brief returns \c true, if a stack parent is set (if available) */
|
||||||
|
virtual bool hasStackParent() const override;
|
||||||
|
/** \brief used to generate stacked plots: returns the upper boundary of this plot in a stack, for the index-th datapoint */
|
||||||
|
double getStackedMax(int index) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // jkqtpgraphsbarchart_H
|
#endif // jkqtpgraphsbarchart_H
|
||||||
|
273
lib/jkqtplotter/graphs/jkqtpbarchartbase.cpp
Normal file
273
lib/jkqtplotter/graphs/jkqtpbarchartbase.cpp
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2020 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This software is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||||
|
the Free Software Foundation, either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License (LGPL) for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "jkqtplotter/graphs/jkqtpbarchartbase.h"
|
||||||
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
JKQTPBarGraphBase::JKQTPBarGraphBase(JKQTBasePlotter* parent):
|
||||||
|
JKQTPXYGraph(parent), width(0.9), shift(0), baseline(0.0)
|
||||||
|
{
|
||||||
|
initFillStyle(parent, parentPlotStyle);
|
||||||
|
initLineStyle(parent, parentPlotStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JKQTPBarGraphBase::JKQTPBarGraphBase(JKQTPlotter* parent):
|
||||||
|
JKQTPBarGraphBase(parent->getPlotter())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
painter.setBrush(b);
|
||||||
|
painter.drawRect(rect);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor JKQTPBarGraphBase::getKeyLabelColor() const {
|
||||||
|
return getFillColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JKQTPBarGraphBase::autoscaleBarWidthAndShift(double maxWidth, double shrinkFactor)
|
||||||
|
{
|
||||||
|
if (parent) {
|
||||||
|
double cntH=0;
|
||||||
|
for (size_t i=0; i<parent->getGraphCount(); i++) {
|
||||||
|
JKQTPPlotElement* g=parent->getGraph(i);
|
||||||
|
JKQTPBarGraphBase* gb=qobject_cast<JKQTPBarGraphBase*>(g);
|
||||||
|
if (gb && considerForAutoscaling(gb)) {
|
||||||
|
cntH++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
double widthH=1.0/cntH*maxWidth*shrinkFactor;
|
||||||
|
double dH=maxWidth/(cntH);
|
||||||
|
double h=0.1+dH/2.0;
|
||||||
|
for (size_t i=0; i<parent->getGraphCount(); i++) {
|
||||||
|
JKQTPPlotElement* g=parent->getGraph(i);
|
||||||
|
JKQTPBarGraphBase* gb=qobject_cast<JKQTPBarGraphBase*>(g);
|
||||||
|
if (gb && considerForAutoscaling(gb)) {
|
||||||
|
if (cntH>1) {
|
||||||
|
gb->width=widthH;
|
||||||
|
gb->shift=h-0.5;
|
||||||
|
h=h+dH;
|
||||||
|
} else {
|
||||||
|
gb->width=maxWidth;
|
||||||
|
gb->shift=0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarGraphBase::autoscaleBarWidthAndShiftSeparatedGroups(double groupWidth) {
|
||||||
|
autoscaleBarWidthAndShift(groupWidth, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void JKQTPBarGraphBase::setColor(QColor c)
|
||||||
|
{
|
||||||
|
setLineColor(c);
|
||||||
|
setFillColor(JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphFillColorDerivationMode, c));
|
||||||
|
c.setAlphaF(0.5);
|
||||||
|
setHighlightingLineColor(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarGraphBase::setShift(double __value)
|
||||||
|
{
|
||||||
|
this->shift = __value;
|
||||||
|
}
|
||||||
|
|
||||||
|
double JKQTPBarGraphBase::getShift() const
|
||||||
|
{
|
||||||
|
return this->shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarGraphBase::setWidth(double __value)
|
||||||
|
{
|
||||||
|
this->width = __value;
|
||||||
|
}
|
||||||
|
|
||||||
|
double JKQTPBarGraphBase::getWidth() const
|
||||||
|
{
|
||||||
|
return this->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarGraphBase::setBaseline(double __value)
|
||||||
|
{
|
||||||
|
this->baseline = __value;
|
||||||
|
}
|
||||||
|
|
||||||
|
double JKQTPBarGraphBase::getBaseline() const
|
||||||
|
{
|
||||||
|
return this->baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPBarGraphBase::setFillColor_and_darkenedColor(QColor fill, int colorDarker)
|
||||||
|
{
|
||||||
|
setFillColor(fill);
|
||||||
|
setLineColor(fill.darker(colorDarker));
|
||||||
|
}
|
||||||
|
|
||||||
|
double JKQTPBarGraphBase::getParentStackedMax(int /*index*/) const
|
||||||
|
{
|
||||||
|
return baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JKQTPBarGraphBase::hasStackParent() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JKQTPBarGraphBase::getValuesMinMax(double &mmin, double &mmax, double &smallestGreaterZero)
|
||||||
|
{
|
||||||
|
mmin=0;
|
||||||
|
mmax=0;
|
||||||
|
smallestGreaterZero=0;
|
||||||
|
if (baseline>0) {
|
||||||
|
smallestGreaterZero=baseline;
|
||||||
|
mmin=baseline;
|
||||||
|
mmax=baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getBarPositionColumn()<0 || getBarHeightColumn()<0) return false;
|
||||||
|
|
||||||
|
const size_t poscol=static_cast<size_t>(getBarPositionColumn());
|
||||||
|
const size_t datacol=static_cast<size_t>(getBarHeightColumn());
|
||||||
|
|
||||||
|
if (parent==nullptr) return false;
|
||||||
|
|
||||||
|
JKQTPDatastore* datastore=parent->getDatastore();
|
||||||
|
int imin=0;
|
||||||
|
int imax=static_cast<int>(qMin(datastore->getRows(poscol), datastore->getRows(datacol)));
|
||||||
|
if (imax<imin) {
|
||||||
|
int h=imin;
|
||||||
|
imin=imax;
|
||||||
|
imax=h;
|
||||||
|
}
|
||||||
|
if (imin<0) imin=0;
|
||||||
|
if (imax<0) imax=0;
|
||||||
|
|
||||||
|
for (int i=imin; i<imax; i++) {
|
||||||
|
double stack=0;
|
||||||
|
double yv=baseline;
|
||||||
|
const double boxstart=getParentStackedMax(i);
|
||||||
|
if (hasStackParent()) {
|
||||||
|
stack=boxstart;
|
||||||
|
yv=stack;
|
||||||
|
}
|
||||||
|
if (JKQTPIsOKFloat(yv)) {
|
||||||
|
if (yv>mmax) mmax=yv;
|
||||||
|
if (yv<mmin) mmin=yv;
|
||||||
|
double xvsgz;
|
||||||
|
xvsgz=yv; SmallestGreaterZeroCompare_xvsgz();
|
||||||
|
}
|
||||||
|
yv=stack+datastore->get(datacol,static_cast<size_t>(i));
|
||||||
|
if (JKQTPIsOKFloat(yv)) {
|
||||||
|
if (yv>mmax) mmax=yv;
|
||||||
|
if (yv<mmin) mmin=yv;
|
||||||
|
double xvsgz;
|
||||||
|
xvsgz=yv; SmallestGreaterZeroCompare_xvsgz();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JKQTPBarGraphBase::getPositionsMinMax(double &mmin, double &mmax, double &smallestGreaterZero)
|
||||||
|
{
|
||||||
|
bool start=true;
|
||||||
|
mmin=0;
|
||||||
|
mmax=0;
|
||||||
|
smallestGreaterZero=0;
|
||||||
|
|
||||||
|
if (getBarPositionColumn()<0 || getBarHeightColumn()<0) return false;
|
||||||
|
|
||||||
|
const size_t poscol=static_cast<size_t>(getBarPositionColumn());
|
||||||
|
const size_t datacol=static_cast<size_t>(getBarHeightColumn());
|
||||||
|
|
||||||
|
if (parent==nullptr) return false;
|
||||||
|
|
||||||
|
JKQTPDatastore* datastore=parent->getDatastore();
|
||||||
|
int imin=0;
|
||||||
|
int imax=static_cast<int>(qMin(datastore->getRows(poscol), datastore->getRows(datacol)));
|
||||||
|
if (imax<imin) {
|
||||||
|
int h=imin;
|
||||||
|
imin=imax;
|
||||||
|
imax=h;
|
||||||
|
}
|
||||||
|
if (imin<0) imin=0;
|
||||||
|
if (imax<0) imax=0;
|
||||||
|
|
||||||
|
for (int i=imin; i<imax; i++) {
|
||||||
|
double xv=datastore->get(poscol,static_cast<size_t>(i));
|
||||||
|
int sr=datastore->getNextLowerIndex(poscol, i);
|
||||||
|
int lr=datastore->getNextHigherIndex(poscol, i);
|
||||||
|
double delta, deltap, deltam;
|
||||||
|
|
||||||
|
if (sr<0 && lr<0) { // only one x-value
|
||||||
|
deltam=0.5;
|
||||||
|
deltap=0.5;
|
||||||
|
} else if (lr<0) { // the right-most x-value
|
||||||
|
deltap=deltam=fabs(xv-datastore->get(poscol,sr))/2.0;
|
||||||
|
} else if (sr<0) { // the left-most x-value
|
||||||
|
deltam=deltap=fabs(datastore->get(poscol,lr)-xv)/2.0;
|
||||||
|
} else {
|
||||||
|
deltam=fabs(xv-datastore->get(poscol,sr))/2.0;
|
||||||
|
deltap=fabs(datastore->get(poscol,lr)-xv)/2.0;
|
||||||
|
}
|
||||||
|
delta=deltap+deltam;
|
||||||
|
|
||||||
|
if (JKQTPIsOKFloat(xv) && JKQTPIsOKFloat(delta) ) {
|
||||||
|
|
||||||
|
if (start || xv+shift*delta+width*delta/2.0>mmax) mmax=xv+shift*delta+width*delta/2.0;
|
||||||
|
if (start || xv+shift*delta-width*delta/2.0<mmin) mmin=xv+shift*delta-width*delta/2.0;
|
||||||
|
double xvsgz;
|
||||||
|
xvsgz=xv+shift*delta+width*delta/2.0; SmallestGreaterZeroCompare_xvsgz();
|
||||||
|
xvsgz=xv+shift*delta-width*delta/2.0; SmallestGreaterZeroCompare_xvsgz();
|
||||||
|
start=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !start;
|
||||||
|
}
|
||||||
|
|
172
lib/jkqtplotter/graphs/jkqtpbarchartbase.h
Normal file
172
lib/jkqtplotter/graphs/jkqtpbarchartbase.h
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2008-2020 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This software is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||||
|
the Free Software Foundation, either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License (LGPL) for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QPainter>
|
||||||
|
#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"
|
||||||
|
#ifndef jkqtpgraphsbarchartbase_H
|
||||||
|
#define jkqtpgraphsbarchartbase_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief This is a base-class for all bar graphs with vertical or horizontal orientation (the orientation is implemented in dervied classes!)
|
||||||
|
* \ingroup jkqtplotter_barssticks
|
||||||
|
*
|
||||||
|
* This class plots a bargraph. This image explains the parameters:
|
||||||
|
*
|
||||||
|
* \image html bargraph_basics.png
|
||||||
|
*
|
||||||
|
* By default the sift parameter is, so the bar is centered at the x-value. The width is 0.9,
|
||||||
|
* so adjacent bars are plotted with a small distance between them. It is possible to use these two parameters
|
||||||
|
* to plot multiple bars for every x-value, by having on JKQTPSpecialLineHorizontalGraph object per
|
||||||
|
* set of bars that belong together. For example for three bars per x-value one would set:
|
||||||
|
* \verbatim
|
||||||
|
* width=0.3
|
||||||
|
* shift=-0.3 / 0 / +0.3
|
||||||
|
* \endverbatim
|
||||||
|
* This results in a bargraph, as shown here:
|
||||||
|
*
|
||||||
|
* \image html plot_bargraphverplot.png
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \see JKQTPBarHorizontalGraph, JKQTPBarVerticalGraph
|
||||||
|
*/
|
||||||
|
class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase: public JKQTPXYGraph, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPBarGraphBase(JKQTBasePlotter* parent=nullptr);
|
||||||
|
/** \brief class constructor */
|
||||||
|
JKQTPBarGraphBase(JKQTPlotter* parent);
|
||||||
|
|
||||||
|
/** \brief plots a key marker inside the specified rectangle \a rect */
|
||||||
|
virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) override;
|
||||||
|
/** \brief returns the color to be used for the key label */
|
||||||
|
virtual QColor getKeyLabelColor() const override;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \copydoc shift */
|
||||||
|
double getShift() const;
|
||||||
|
/*! \copydoc width */
|
||||||
|
double getWidth() const;
|
||||||
|
/*! \copydoc baseline */
|
||||||
|
double getBaseline() const;
|
||||||
|
/** \brief sets the fill color and the color together, where fillColor is set to \a fill and the line-color is set to \c fill.darker(colorDarker)
|
||||||
|
* \see setColor()
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
/** \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;
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
/** \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
|
||||||
|
* \param shrinkFactor factor, by which the bar are shrinked compared to the available space
|
||||||
|
*
|
||||||
|
* \note This function will scale ALL graphs of the parent plot, which were derived from JKQTPBarHorizontalGraph, that match in orientation (as returned by isHorizontal() ).
|
||||||
|
*/
|
||||||
|
virtual void autoscaleBarWidthAndShift(double maxWidth=0.9, double shrinkFactor=0.8);
|
||||||
|
|
||||||
|
/** \brief equivalent to \c autoscaleBarWidthAndShift(groupWidth,1);
|
||||||
|
*/
|
||||||
|
void autoscaleBarWidthAndShiftSeparatedGroups(double groupWidth=0.75);
|
||||||
|
/*! \copydoc shift */
|
||||||
|
void setShift(double __value);
|
||||||
|
/*! \copydoc width */
|
||||||
|
void setWidth(double __value);
|
||||||
|
/*! \copydoc baseline */
|
||||||
|
void setBaseline(double __value);
|
||||||
|
|
||||||
|
/** \brief set outline and fill color at the same time
|
||||||
|
* \see setFillColor_and_darkenedColor()
|
||||||
|
*/
|
||||||
|
virtual void setColor(QColor c);
|
||||||
|
|
||||||
|
|
||||||
|
/** \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;
|
||||||
|
|
||||||
|
/** \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;
|
||||||
|
|
||||||
|
/** \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;
|
||||||
|
|
||||||
|
/** \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;
|
||||||
|
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:
|
||||||
|
* \image html bargraph_basics.png
|
||||||
|
*/
|
||||||
|
double width;
|
||||||
|
/** \brief the shift of the bargraphs, relative to the distance between the current and the next x-value
|
||||||
|
*
|
||||||
|
* See the following graphic to understand this concept:
|
||||||
|
* \image html bargraph_basics.png
|
||||||
|
*/
|
||||||
|
double shift;
|
||||||
|
|
||||||
|
/** \brief baseline of the plot (NOTE: 0 is interpreted as until plot border in log-mode!!!)
|
||||||
|
*/
|
||||||
|
double baseline;
|
||||||
|
|
||||||
|
/** \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) */
|
||||||
|
virtual bool considerForAutoscaling( JKQTPBarGraphBase* other) const=0;
|
||||||
|
|
||||||
|
/** \brief used to generate stacked plots: returns the upper boundary of the parent plot in a stack, for the index-th datapoint */
|
||||||
|
virtual double getParentStackedMax(int index) const ;
|
||||||
|
|
||||||
|
/** \brief returns \c true, if a stack parent is set (if available) */
|
||||||
|
virtual bool hasStackParent() const ;
|
||||||
|
|
||||||
|
/** \brief get the maximum and minimum value in the box-elongation (i.e. value) direction of the graph
|
||||||
|
*
|
||||||
|
* The result is given in the two parameters which are call-by-reference parameters!
|
||||||
|
*/
|
||||||
|
bool getValuesMinMax(double& mmin, double& mmax, double& smallestGreaterZero) ;
|
||||||
|
/** \brief get the maximum and minimum value of the box positions of the graph
|
||||||
|
*
|
||||||
|
* The result is given in the two parameters which are call-by-reference parameters!
|
||||||
|
*/
|
||||||
|
bool getPositionsMinMax(double& mmin, double& mmax, double& smallestGreaterZero) ;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // jkqtpgraphsbarchartbase_H
|
BIN
screenshots/barchart_hor.png
Normal file
BIN
screenshots/barchart_hor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Loading…
Reference in New Issue
Block a user