mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-26 10:31:39 +08:00
f40bb2010d
NEW: autoscaling for barcharts works now, also when stacked and unstacked charts are combined in one plot NEW: proper styling for financial graphs in style.ini-files REWORKED: separation and gruping factor for barcharts on autoscaling doc update
183 lines
7.1 KiB
C++
183 lines
7.1 KiB
C++
/** \example barchart.cpp
|
|
* Shows how to draw Barcharts with JKQTPlotter
|
|
*
|
|
* \ref JKQTPlotterBarcharts
|
|
*/
|
|
|
|
#include "jkqtpexampleapplication.h"
|
|
#include <QApplication>
|
|
#include "jkqtplotter/jkqtplotter.h"
|
|
#include "jkqtplotter/graphs/jkqtpscatter.h"
|
|
#include "jkqtplotter/graphs/jkqtpbarchart.h"
|
|
#include "jkqtpexampleapplication.h"
|
|
|
|
#define Ndata 5
|
|
|
|
|
|
template <class TCHART>
|
|
std::vector<TCHART*> doExample(JKQTPlotter& plot, const QString& title)
|
|
{
|
|
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
|
|
plot.getPlotter()->setUseAntiAliasingForGraphs(true); // nicer (but slower) plotting
|
|
plot.getPlotter()->setUseAntiAliasingForSystem(true); // nicer (but slower) plotting
|
|
plot.getPlotter()->setUseAntiAliasingForText(true); // nicer (but slower) text rendering
|
|
JKQTPDatastore* ds=plot.getDatastore();
|
|
|
|
// 2. now we create data for three simple barchart
|
|
QString L[Ndata]={ "cat. A", "cat. C", "cat. B", "cat. D", "other"}; // unsorted category axis
|
|
double X[Ndata]={ 1, 3, 2, 4, 5};
|
|
//QString L[Ndata]={ "cat. A", "cat. B", "cat. C", "cat. D", "other"}; // correctly sorted data!
|
|
//double X[Ndata]={ 1, 2, 3, 4, 5};
|
|
double Y1[Ndata]={ 5, 4, 3, 4, 5};
|
|
double Y2[Ndata]={ -5, -3, 1, 3, 6};
|
|
double Y3[Ndata]={ 6, 2, 5, 3, 6};
|
|
|
|
// 3. make data available to JKQTPlotter by adding it to the internal datastore.
|
|
// Note: In this step the data is copied (of not specified otherwise)
|
|
// the variables columnX and columnY... will contain the internal column ID of the
|
|
// newly created columns with names "x" and "y..." and the (copied) data from X
|
|
// and Y...
|
|
size_t columnX=ds->addCopiedColumn(X, Ndata, "x");
|
|
size_t columnY1=ds->addCopiedColumn(Y1, Ndata, "y1");
|
|
size_t columnY2=ds->addCopiedColumn(Y2, Ndata, "y2");
|
|
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:
|
|
TCHART* graph1=new TCHART(&plot);
|
|
graph1->setBarPositionColumn(columnX);
|
|
graph1->setBarHeightColumn(columnY1);
|
|
graph1->setTitle(QObject::tr("dataset 1"));
|
|
TCHART* graph2=new TCHART(&plot);
|
|
graph2->setBarPositionColumn(columnX);
|
|
graph2->setBarHeightColumn(columnY2);
|
|
graph2->setTitle(QObject::tr("dataset 2"));
|
|
TCHART* graph3=new TCHART(&plot);
|
|
graph3->setBarPositionColumn(columnX);
|
|
graph3->setBarHeightColumn(columnY3);
|
|
graph3->setTitle(QObject::tr("dataset 3"));
|
|
|
|
|
|
// 5. add the graphs to the plot, so it is actually displayed
|
|
plot.addGraph(graph1);
|
|
plot.addGraph(graph2);
|
|
plot.addGraph(graph3);
|
|
|
|
// 6. now we set the graphs, so they are plotted side-by-side
|
|
// This function searches all JKQTPBarHorizontalGraph in the current
|
|
// plot and sets their shift/scale so they form a nice plot with
|
|
// side-by-side groups
|
|
graph1->autoscaleBarWidthAndShift();
|
|
|
|
if (dynamic_cast<JKQTPBarVerticalGraph*>(graph1)!=nullptr) {
|
|
// 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.getXAxis()->addAxisTickLabels(X, L, Ndata);
|
|
// also we can rotate the labels a bit (by 45 degree), so they fit better
|
|
plot.getXAxis()->setTickLabelAngle(45);
|
|
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
|
|
// and lay it out as a single row
|
|
// NOTE: plot is a descendent of QWidget, which uses an internal object of
|
|
// type JKQTBasePlotter, which does the actual plotting.
|
|
// So many properties of the plot are only available in this internal
|
|
// object, which you can access by plot.getPlotter().
|
|
plot.getPlotter()->setKeyPosition(JKQTPKeyOutsideTopRight);
|
|
plot.getMainKey()->setLayout(JKQTPKeyLayoutOneRow);
|
|
|
|
// 9 autoscale the plot so the graph is contained
|
|
plot.zoomToFit();
|
|
|
|
// show plotter and make it a decent size
|
|
plot.setWindowTitle(title);
|
|
plot.show();
|
|
plot.resize(600/plot.devicePixelRatioF(),550/plot.devicePixelRatioF());
|
|
|
|
return {graph1, graph2, graph3};
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
|
|
JKQTPAppSettingController highDPIController(argc,argv);
|
|
JKQTPExampleApplication app(argc, argv);
|
|
|
|
JKQTPlotter plotV;
|
|
auto gV=doExample<JKQTPBarVerticalGraph>(plotV, "1: JKQTPBarVerticalGraph");
|
|
JKQTPlotter plotH;
|
|
auto gH=doExample<JKQTPBarHorizontalGraph>(plotH, "2: JKQTPBarHorizontalGraph");
|
|
|
|
app.addExportStepFunctor([&](){
|
|
for (auto g: gV) {
|
|
g->setDrawBaseline(false);
|
|
}
|
|
for (auto g: gH) {
|
|
g->setDrawBaseline(false);
|
|
}
|
|
plotV.getXAxis()->setShowZeroAxis(false);
|
|
plotV.getYAxis()->setShowZeroAxis(false);
|
|
plotH.getXAxis()->setShowZeroAxis(false);
|
|
plotH.getYAxis()->setShowZeroAxis(false);
|
|
plotV.redrawPlot();
|
|
plotH.redrawPlot();
|
|
});
|
|
|
|
app.addExportStepFunctor([&](){
|
|
for (auto g: gV) {
|
|
g->setDrawBaseline(true);
|
|
}
|
|
for (auto g: gH) {
|
|
g->setDrawBaseline(true);
|
|
}
|
|
plotV.getXAxis()->setShowZeroAxis(false);
|
|
plotV.getYAxis()->setShowZeroAxis(false);
|
|
plotH.getXAxis()->setShowZeroAxis(false);
|
|
plotH.getYAxis()->setShowZeroAxis(false);
|
|
plotV.redrawPlot();
|
|
plotH.redrawPlot();
|
|
});
|
|
|
|
app.addExportStepFunctor([&](){
|
|
for (auto g: gV) {
|
|
g->setDrawBaseline(false);
|
|
}
|
|
for (auto g: gH) {
|
|
g->setDrawBaseline(false);
|
|
}
|
|
gV[0]->autoscaleBarWidthAndShift(1,0.9);
|
|
gH[0]->autoscaleBarWidthAndShift(1,0.9);
|
|
plotV.getXAxis()->setShowZeroAxis(false);
|
|
plotV.getYAxis()->setShowZeroAxis(false);
|
|
plotH.getXAxis()->setShowZeroAxis(false);
|
|
plotH.getYAxis()->setShowZeroAxis(false);
|
|
plotV.redrawPlot();
|
|
plotH.redrawPlot();
|
|
});
|
|
|
|
app.addExportStepFunctor([&](){
|
|
for (auto g: gV) {
|
|
g->setDrawBaseline(false);
|
|
}
|
|
for (auto g: gH) {
|
|
g->setDrawBaseline(false);
|
|
}
|
|
gV[0]->autoscaleBarWidthAndShift(0.75,1);
|
|
gH[0]->autoscaleBarWidthAndShift(0.75,1);
|
|
plotV.getXAxis()->setShowZeroAxis(false);
|
|
plotV.getYAxis()->setShowZeroAxis(false);
|
|
plotH.getXAxis()->setShowZeroAxis(false);
|
|
plotH.getYAxis()->setShowZeroAxis(false);
|
|
plotV.redrawPlot();
|
|
plotH.redrawPlot();
|
|
});
|
|
return app.exec();
|
|
}
|