UPDATED: styles doc image generation and doc images from that

This commit is contained in:
jkriege2 2023-07-22 00:14:42 +02:00
parent b6b5c48d9e
commit 84acf7f54a
31 changed files with 503 additions and 467 deletions

View File

@ -115,6 +115,14 @@ if(JKQtPlotter_BUILD_TOOLS)
)
add_dependencies(JKQTPlotter_GenerateDocImages JKQTPlotter_GenerateDocImages_listerrorindicators)
add_custom_target(JKQTPlotter_GenerateDocImages_listpalettes
COMMENT "Building JKQTPlotter Documentation Images: listpalettes"
COMMAND ${JKQTPlotter_GenerateDocImages_COMMAND} --listpalettes --iconsize=256 --outputdir="${JKQTPlotter_GenerateDocImages_OutputDir}/palettes/"
WORKING_DIRECTORY ${JKQtPlotter_QT_BINDIR}
DEPENDS jkqtplotter_doc_imagegenerator
)
add_dependencies(JKQTPlotter_GenerateDocImages JKQTPlotter_GenerateDocImages_listpalettes)
add_custom_target(JKQTPlotter_GenerateDocImages_listaxisstyleprops
COMMENT "Building JKQTPlotter Documentation Images: listaxisstyleprops"
COMMAND ${JKQTPlotter_GenerateDocImages_COMMAND} --listaxisstyleprops --background=lightgrey --iconsize=50 --outputdir="${JKQTPlotter_GenerateDocImages_OutputDir}/axisstyle/"
@ -125,11 +133,11 @@ if(JKQtPlotter_BUILD_TOOLS)
add_custom_target(JKQTPlotter_GenerateDocImages_liststyles
COMMENT "Building JKQTPlotter Documentation Images: liststyles"
COMMAND ${JKQTPlotter_GenerateDocImages_COMMAND} --liststyles --iconsize=500 --outputdir="${JKQTPlotter_GenerateDocImages_OutputDir}/styles/" --doctomodify="${JKQTPlotter_GenerateDocImages_dox}/jkqtplotter_styling.dox"
COMMAND ${JKQTPlotter_GenerateDocImages_COMMAND} --liststyles --iconsize=1200 --outputdir="${JKQTPlotter_GenerateDocImages_OutputDir}/styles/" --doctomodify="${JKQTPlotter_GenerateDocImages_dox}/jkqtplotter_styling.dox"
WORKING_DIRECTORY ${JKQtPlotter_QT_BINDIR}
DEPENDS jkqtplotter_doc_imagegenerator
)
add_dependencies(JKQTPlotter_GenerateDocImages JKQTPlotter_GenerateDocImages_listaxisstyleprops)
add_dependencies(JKQTPlotter_GenerateDocImages JKQTPlotter_GenerateDocImages_liststyles)
endif(JKQtPlotter_BUILD_TOOLS)

View File

@ -48,21 +48,25 @@ Here is a table with all available ready-made styles:
<th>Screenshot
<th>Symbols
<tr>
<td><a href="https://github.com/jkriege2/JKQtPlotter/tree/master/lib/jkqtplotter/resources/styles/blackandwhite.ini"><code>:/JKQTPlotter/styles/blackandwhite.ini</code></a>
<td>\image html blackandwhite.ini.png
<td>\image html blackandwhite.ini.symbols.png
<td><a href="https://github.com/jkriege2/JKQtPlotter/tree/master/lib/jkqtplotter/resources/styles/default.ini"><code>:/JKQTPlotter/styles/default.ini</code></a>
<td>\image html default.ini.png
<td>\image html default.ini.symbols.png
<tr>
<td><a href="https://github.com/jkriege2/JKQtPlotter/tree/master/lib/jkqtplotter/resources/styles/blueprint.ini"><code>:/JKQTPlotter/styles/blueprint.ini</code></a>
<td>\image html blueprint.ini.png
<td>\image html blueprint.ini.symbols.png
<tr>
<td><a href="https://github.com/jkriege2/JKQtPlotter/tree/master/lib/jkqtplotter/resources/styles/cyberpunk.ini"><code>:/JKQTPlotter/styles/cyberpunk.ini</code></a>
<td>\image html cyberpunk.ini.png
<td>\image html cyberpunk.ini.symbols.png
<tr>
<td><a href="https://github.com/jkriege2/JKQtPlotter/tree/master/lib/jkqtplotter/resources/styles/dark.ini"><code>:/JKQTPlotter/styles/dark.ini</code></a>
<td>\image html dark.ini.png
<td>\image html dark.ini.symbols.png
<tr>
<td><a href="https://github.com/jkriege2/JKQtPlotter/tree/master/lib/jkqtplotter/resources/styles/default.ini"><code>:/JKQTPlotter/styles/default.ini</code></a>
<td>\image html default.ini.png
<td>\image html default.ini.symbols.png
<td><a href="https://github.com/jkriege2/JKQtPlotter/tree/master/lib/jkqtplotter/resources/styles/blackandwhite.ini"><code>:/JKQTPlotter/styles/blackandwhite.ini</code></a>
<td>\image html blackandwhite.ini.png
<td>\image html blackandwhite.ini.symbols.png
<tr>
<td><a href="https://github.com/jkriege2/JKQtPlotter/tree/master/lib/jkqtplotter/resources/styles/legacy_default_style.ini"><code>:/JKQTPlotter/styles/legacy_default_style.ini</code></a>
<td>\image html legacy_default_style.ini.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -8,7 +8,7 @@ message( STATUS ".. Building Example ${EXAMPLE_NAME}" )
# Set up source files
set(SOURCES test_styling.cpp test_styling_main.cpp jkqtpstyleplaintextedit.cpp)
set(HEADERS test_styling.h jkqtpstyleplaintextedit.h )
set(HEADERS test_styling.h build_test_graphs.h jkqtpstyleplaintextedit.h )
set(RESOURCES )
set(UIS test_styling.ui )

View File

@ -0,0 +1,322 @@
#ifndef BUILD_TEST_GRAPHS_H
#define BUILD_TEST_GRAPHS_H
#include "jkqtplotter/graphs/jkqtpscatter.h"
#include "jkqtplotter/graphs/jkqtpbarchart.h"
#include "jkqtplotter/graphs/jkqtpimage.h"
#include "jkqtplotter/graphs/jkqtpgeometric.h"
#include "jkqtplotter/graphs/jkqtpgeoannotations.h"
#include "jkqtplotter/graphs/jkqtpboxplot.h"
#include "jkqtplotter/graphs/jkqtpfilledcurve.h"
#include "jkqtplotter/graphs/jkqtpimpulses.h"
#include "jkqtplotter/jkqtpbaseplotter.h"
#define DEFAULT_PLOT_SIZE QSize(4,2)
inline void setupGridPrintingAndDatastores(QVector<JKQTBasePlotter*>& plots, QSize size) {
// connect plots
for (auto plt: plots) {
for (int x=0; x<size.width(); x++) {
for (int y=0; y<size.height(); y++) {
plt->addGridPrintingPlotter(x,y, plots[y*size.width()+x]);
}
}
plt->setGridPrinting(true);
// use same datastore for each plot
if (plt!=plots.first()) plt->useExternalDatastore(plots.first()->getDatastore());
}
}
inline void buildPlots(QVector<JKQTBasePlotter*>& plots) {
// 0. get a pointer to the internal datastore (for convenience)
JKQTPDatastore* ds=plots.first()->getDatastore();
// 1. clear old graphs/data
for (auto plt: plots) {
plt->clearGraphs(true);
}
ds->clear();
// 2. now we create data for a simple plot (a sine curve)
QVector<double> X, Y1, Y2, img, X3, Y3, Y3err, Xbar, Ybar, Ybar2, Ybar3, Y4, Y5, XImp, YImp, XBP, MinBP, Q25BP, MeanBP, MedianBP, Q75BP, MaxBP;
const int Ndata=50;
for (int i=0; i<Ndata; i++) {
const double x=double(i)/double(Ndata)*8.0*JKQTPSTATISTICS_PI;
X<<x;
Y1<<3.1+sin(x)+x/25.0*2.0;
Y2<<3.1+1.5*sin(x)*exp(-0.2*x)+x/25.0*2.0;
Y4<<4.5*exp(-x/10.0);
Y5<<2.0*exp(-x/10.0)+0.8;
if (i%5==0) {
X3<<x;
Y3<<(4.5)+sin(x/25.0*JKQTPSTATISTICS_PI)*2.0-x/12.5;
Y3err<<(double(i+5)/double(Ndata)*0.5);
}
if (i>0 && i%16==0) {
Xbar<<x;
Ybar<<(double(i+5)/double(Ndata)*(1.5));
Ybar2<<(double(i+5)/double(Ndata)*(1.2));
Ybar3<<(3.0-(double(i+5)/double(Ndata)*(3.7)));
}
if (i%8==0) {
XImp<<1+x/1.2;
YImp<<1.5+1.1*cos(x/2.0);
}
if (i<=5) {
XBP<<(i-1);
MinBP<<(i+1);
Q25BP<<(i*1.1+3.0);
MeanBP<<(i*1.12+4.0);
MedianBP<<(i*1.2+3.5);
Q75BP<<(i*1.3+6.0);
MaxBP<<(i*1.35+7.5);
}
}
auto fgauss=[](double x, double y, double x0, double y0, double sx, double sy) {
return exp(-2.0*(x-x0)*(x-x0)/sx/sx-2.0*(y-y0)*(y-y0)/sy/sy);
};
for (int i=0; i<Ndata; i++) {
for (int j=0; j<Ndata; j++) {
img.push_back(fgauss(j,i,Ndata/3,Ndata/3,Ndata/5,Ndata/3)+fgauss(j,i,Ndata*3/4,Ndata*2/3,Ndata/2,Ndata/4));
}
}
// 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), so you can
// reuse X and Y afterwards!
// 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, "x");
size_t columnY1=ds->addCopiedColumn(Y1, "y1");
size_t columnY2=ds->addCopiedColumn(Y2, "y2");
size_t columnImg=ds->addCopiedColumn(img, "img");
size_t columnX3=ds->addCopiedColumn(X3, "x3");
size_t columnY3=ds->addCopiedColumn(Y3, "y3");
size_t columnY3err=ds->addCopiedColumn(Y3err, "y3err");
size_t columnXbar=ds->addCopiedColumn(Xbar, "xbar");
size_t columnYbar=ds->addCopiedColumn(Ybar, "ybar");
size_t columnYbar2=ds->addCopiedColumn(Ybar2, "Ybar2");
size_t columnYbar3=ds->addCopiedColumn(Ybar3, "Ybar3");
size_t columnY4=ds->addCopiedColumn(Y4, "y4");
size_t columnY5=ds->addCopiedColumn(Y5, "y5");
size_t columnXImp=ds->addCopiedColumn(XImp, "ximp");
size_t columnYImp=ds->addCopiedColumn(YImp, "yimp");
size_t columnXBP=ds->addCopiedColumn(XBP, "XBP");
size_t columnMinBP=ds->addCopiedColumn(MinBP, "MinBP");
size_t columnQ25BP=ds->addCopiedColumn(Q25BP, "Q25BP");
size_t columnMeanBP=ds->addCopiedColumn(MeanBP, "MeanBP");
size_t columnMedianBP=ds->addCopiedColumn(MedianBP, "MedianBP");
size_t columnQ75BP=ds->addCopiedColumn(Q75BP, "Q75BP");
size_t columnMaxBP=ds->addCopiedColumn(MaxBP, "MaxBP");
// 4. create diverse graphs in the plot:
JKQTPFilledCurveXGraph* graphf4=new JKQTPFilledCurveXGraph(plots[2]);
graphf4->setXColumn(columnX);
graphf4->setYColumn(columnY4);
graphf4->setTitle(QObject::tr("filled exp-function"));
plots[2]->addGraph(graphf4);
JKQTPFilledCurveXGraph* graphf5=new JKQTPFilledCurveXGraph(plots[2]);
graphf5->setXColumn(columnX);
graphf5->setYColumn(columnY5);
graphf5->setTitle(QObject::tr("other filled exp-function"));
plots[2]->addGraph(graphf5);
JKQTPColumnMathImage* graphI=new JKQTPColumnMathImage(plots.last());
graphI->setImageColumn(columnImg);
graphI->setNx(Ndata);
graphI->setNy(Ndata);
graphI->setColorBarTopVisible(true);
graphI->setColorBarRightVisible(true);
graphI->setX(0.5);
graphI->setY(-2.0);
graphI->setWidth(5);
graphI->setHeight(1);
graphI->setTitle(QObject::tr("2{\\times}Gauss"));
plots.last()->addGraph(graphI);
JKQTPXYLineErrorGraph* graph1=new JKQTPXYLineErrorGraph(plots[0]);
graph1->setXColumn(columnX3);
graph1->setYColumn(columnY3);
graph1->setYErrorColumn(columnY3err);
graph1->setDrawLine(true);
graph1->setYErrorStyle(JKQTPErrorBarsLines);
graph1->setSymbolType(JKQTPNoSymbol);
graph1->setTitle(QObject::tr("sine \\pm errors graph"));
plots[0]->addGraph(graph1);
JKQTPXYLineGraph* graph2=new JKQTPXYLineGraph(plots[0]);
graph2->setXColumn(columnX);
graph2->setYColumn(columnY1);
graph2->setSymbolType(JKQTPNoSymbol);
graph2->setTitle(QObject::tr("sine graph $f(x)=\\sin(x)$"));
plots[0]->addGraph(graph2);
JKQTPXYLineGraph* graph3=new JKQTPXYLineGraph(plots[0]);
graph3->setXColumn(columnX);
graph3->setYColumn(columnY2);
graph3->setSymbolType(JKQTPNoSymbol);
//graph2->setTitle(QObject::tr("sine{\\cdot}exp graph $f(x)=\\sin(x)\\cdot\\exp\\left(-\\frac{x}{5}\\right)$"));
graph3->setTitle(QObject::tr("sine*exp graph"));
plots[0]->addGraph(graph3);
JKQTPImpulsesVerticalGraph* graphi2=new JKQTPImpulsesVerticalGraph(plots[0]);
graphi2->setXColumn(columnXImp);
graphi2->setYColumn(columnYImp);
graphi2->setTitle(QObject::tr("impulses"));
plots[0]->addGraph(graphi2);
JKQTPXYLineErrorGraph* graph1s=new JKQTPXYLineErrorGraph(plots[1]);
graph1s->setXColumn(columnX3);
graph1s->setYColumn(columnY3);
graph1s->setYErrorColumn(columnY3err);
graph1s->setDrawLine(false);
graph1s->setYErrorStyle(JKQTPErrorBars);
graph1s->setTitle(QObject::tr("sine \\pm errors graph"));
plots[1]->addGraph(graph1s);
JKQTPXYScatterGraph* graph2s=new JKQTPXYScatterGraph(plots[1]);
graph2s->setXColumn(columnX);
graph2s->setYColumn(columnY1);
graph2s->setTitle(QObject::tr("sine graph $f(x)=\\sin(x)$"));
plots[1]->addGraph(graph2s);
JKQTPXYScatterGraph* graph3s=new JKQTPXYScatterGraph(plots[1]);
graph3s->setXColumn(columnX);
graph3s->setYColumn(columnY2);
graph3s->setTitle(QObject::tr("sine*exp graph"));
plots[1]->addGraph(graph3s);
JKQTPBarVerticalGraph* graphb=new JKQTPBarVerticalGraph(plots[3]);
graphb->setXColumn(columnXbar);
graphb->setYColumn(columnYbar);
graphb->setTitle(QObject::tr("barchart"));
plots[3]->addGraph(graphb);
JKQTPBarVerticalGraph* graphb2=new JKQTPBarVerticalGraph(plots[3]);
graphb2->setXColumn(columnXbar);
graphb2->setYColumn(columnYbar2);
graphb2->setTitle(QObject::tr("2^{nd} barchart"));
plots[3]->addGraph(graphb2);
JKQTPBarVerticalGraph* graphb3=new JKQTPBarVerticalGraph(plots[3]);
graphb3->setXColumn(columnXbar);
graphb3->setYColumn(columnYbar3);
graphb3->setTitle(QObject::tr("3^{nd} barchart"));
plots[3]->addGraph(graphb3);
graphb3->autoscaleBarWidthAndShiftSeparatedGroups();
JKQTPBoxplotVerticalGraph* graphBP=new JKQTPBoxplotVerticalGraph(plots[plots.size()/2]);
graphBP->setPositionColumn(columnXBP);
graphBP->setMinColumn(columnMinBP);
graphBP->setPercentile25Column(columnQ25BP);
graphBP->setMeanColumn(columnMeanBP);
graphBP->setMedianColumn(columnMedianBP);
graphBP->setPercentile75Column(columnQ75BP);
graphBP->setMaxColumn(columnMaxBP);
plots[plots.size()/2]->addGraph(graphBP);
auto plotgeo=*(plots.rbegin()+1);
JKQTPGeoSymbol* annotSym=new JKQTPGeoSymbol(plotgeo, -1.5, 3);
plotgeo->addGraph(annotSym);
JKQTPGeoText* annotTxt=new JKQTPGeoText(plotgeo, annotSym->getX()+0.5, annotSym->getY(), "Annotation $\\int_{0}^{2\\pi}\\sin(x)\\;\\mathrm{d}x$");
plotgeo->addGraph(annotTxt);
JKQTPGeoEllipse* geoEll=new JKQTPGeoEllipse(plotgeo, 1.5,0.5,3.5,1.2);
geoEll->setAngle(-25);
plotgeo->addGraph(geoEll);
plotgeo->addGraph(new JKQTPGeoArrow(plotgeo, geoEll->getCenter(),annotSym->getP()-QPointF(0.5,0.5)));
plotgeo->addGraph(new JKQTPGeoLine(plotgeo, geoEll->getCenter(),QPointF(annotSym->getX(),annotSym->getY()-2.0)));
// 6. autoscale the plot so the graph is contained
for (auto plt: plots) {
plt->zoomToFit();
plt->getXAxis()->setAxisLabel("x-axis");
plt->getYAxis()->setAxisLabel("y-axis");
}
plots[0]->getYAxis()->setRange(plots[0]->getYAxis()->getMin(), 8);
plots[1]->getYAxis()->setRange(plots[1]->getYAxis()->getMin(), 8);
plots[3]->getYAxis()->setRange(plots[3]->getYAxis()->getMin(), 2.5);
plotgeo->setMaintainAspectRatio(true);
plotgeo->setMaintainAxisAspectRatio(true);
plotgeo->getXAxis()->setRange(-2.5,4);
plotgeo->getYAxis()->setRange(-2.5,4);
plots[0]->setPlotLabel("Line Graphs");
plots[1]->setPlotLabel("Scatter Graphs");
plots[2]->setPlotLabel("Filled Graphs");
plots[3]->setPlotLabel("Bar Charts");
plots[plots.size()/2]->setPlotLabel("Boxplots");
plotgeo->setPlotLabel("Geometry & Annotations");
plots.last()->setPlotLabel("Image Plot");
}
inline void buildLineSymbolSampler(JKQTBasePlotter* plotExtra, JKQTBasePlotter* baseplot) {
plotExtra->clearGraphs(true);
plotExtra->setBackgroundColor(baseplot->getBackgroundColor());
plotExtra->setExportBackgroundColor(baseplot->getExportBackgroundColor());
plotExtra->setPlotBackgroundColor(baseplot->getPlotBackgroundColor());
plotExtra->getXAxis()->setDrawMode1(JKQTPCADMnone);
plotExtra->getXAxis()->setDrawMode2(JKQTPCADMnone);
plotExtra->getYAxis()->setDrawMode1(JKQTPCADMnone);
plotExtra->getYAxis()->setDrawMode2(JKQTPCADMnone);
double x=1;
double xlineend=6;
double y=1;
double xmax=15;
int cnt=0;
const QColor defaultColor=baseplot->getCurrentPlotterStyle().graphsStyle.defaultGraphColors.first();
for (auto s: baseplot->getCurrentPlotterStyle().graphsStyle.defaultGraphSymbols) {
plotExtra->addGraph(new JKQTPGeoSymbol(plotExtra, x, y, s, 12, defaultColor, defaultColor.lighter() ));
x+=1;
xmax=qMax(x, xmax);
if (cnt>0 && cnt%25==0) {
x=1;
y+=1.0;
}
cnt++;
}
y=y+1;
double ycoltest=y;
for (auto s: baseplot->getCurrentPlotterStyle().graphsStyle.defaultGraphPenStyles) {
JKQTPGeoLine* l;
plotExtra->addGraph(l=new JKQTPGeoLine(plotExtra, 1,y,xlineend,y)); l->setStyle(defaultColor, 2, s);
plotExtra->addGraph(l=new JKQTPGeoLine(plotExtra, 1,y-0.25,xlineend,y-0.25)); l->setStyle(defaultColor.darker(), 1, s);
y+=0.75;
}
x=xlineend+1;
const int cntFillTests=qMax(baseplot->getCurrentPlotterStyle().graphsStyle.defaultGraphColors.size(), baseplot->getCurrentPlotterStyle().graphsStyle.defaultGraphFillStyles.size());
double dx=(xmax-xlineend-1.0)/static_cast<double>(cntFillTests);
for (int i=0; i<cntFillTests; i++) {
const auto col=baseplot->getCurrentPlotterStyle().graphsStyle.defaultGraphColors.value(i%baseplot->getCurrentPlotterStyle().graphsStyle.defaultGraphColors.size(), Qt::black);
const auto fs=baseplot->getCurrentPlotterStyle().graphsStyle.defaultGraphFillStyles.value(i%baseplot->getCurrentPlotterStyle().graphsStyle.defaultGraphFillStyles.size(), Qt::SolidPattern);
JKQTPGeoLine* l;
plotExtra->addGraph(l=new JKQTPGeoLine(plotExtra, x,ycoltest,x,y-0.5)); l->setStyle(col,5);
JKQTPGeoRectangle* r;
plotExtra->addGraph(r=new JKQTPGeoRectangle(plotExtra, x+dx/2,(ycoltest+y-0.5)/2.0, dx*0.5, y-ycoltest-0.5));
r->setStyle(col,1, Qt::SolidLine, JKQTPGetDerivedColor(baseplot->getCurrentPlotterStyle().graphsStyle.defaultGraphStyle.fillColorDerivationMode, col), fs);
x+=dx;
}
plotExtra->zoomToFit();
plotExtra->setX(0, plotExtra->getXMax()+2);
plotExtra->setY(0, plotExtra->getYMax()+1);
plotExtra->setGrid(false);
plotExtra->setPlotLabel("default symbols/lines/colors");
}
#endif // BUILD_TEST_GRAPHS_H

View File

@ -1,14 +1,7 @@
#include "test_styling.h"
#include "build_test_graphs.h"
#include "ui_test_styling.h"
#include "jkqtplotter/jkqtplotter.h"
#include "jkqtplotter/graphs/jkqtpscatter.h"
#include "jkqtplotter/graphs/jkqtpbarchart.h"
#include "jkqtplotter/graphs/jkqtpimage.h"
#include "jkqtplotter/graphs/jkqtpgeometric.h"
#include "jkqtplotter/graphs/jkqtpgeoannotations.h"
#include "jkqtplotter/graphs/jkqtpboxplot.h"
#include "jkqtplotter/graphs/jkqtpfilledcurve.h"
#include "jkqtplotter/graphs/jkqtpimpulses.h"
#include <QDir>
#include <QTextStream>
@ -20,18 +13,29 @@ TestStyling::TestStyling(QWidget *parent) :
{
// set up the GUI
ui->setupUi(this);
ui->splitter->setStretchFactor(0,1);
ui->splitter->setStretchFactor(0,2);
ui->splitter->setStretchFactor(1,1);
plots=QVector<JKQTPlotter*>{ui->plot1, ui->plot2, ui->plot3, ui->plot4, ui->plot5, ui->plot6, ui->plot7, ui->plot8};
for (auto p: plots) {
bplots<<p->getPlotter();
}
// connect plots
setupGridPrintingAndDatastores(bplots, QSize(4,2));
// initialize a simple plot
initPlot();
// connect GUI to JKQTPlotter
connect(ui->chkGrid, SIGNAL(toggled(bool)), ui->plot, SLOT(setGrid(bool)));
connect(ui->chkLogX, SIGNAL(toggled(bool)), ui->plot->getXAxis(), SLOT(setLogAxis(bool)));
connect(ui->chkLogY, SIGNAL(toggled(bool)), ui->plot->getYAxis(), SLOT(setLogAxis(bool)));
connect(ui->chkDebugBoxes, SIGNAL(toggled(bool)), ui->plot->getPlotter(), SLOT(enableDebugShowRegionBoxes(bool)));
connect(ui->chkDebugTextBoxes, SIGNAL(toggled(bool)), ui->plot->getPlotter(), SLOT(enableDebugShowTextBoxes(bool)));
for (auto plt: plots) {
connect(ui->chkGrid, SIGNAL(toggled(bool)), plt, SLOT(setGrid(bool)));
connect(ui->chkLogX, SIGNAL(toggled(bool)), plt->getXAxis(), SLOT(setLogAxis(bool)));
connect(ui->chkLogY, SIGNAL(toggled(bool)), plt->getYAxis(), SLOT(setLogAxis(bool)));
connect(ui->chkDebugBoxes, SIGNAL(toggled(bool)), plt->getPlotter(), SLOT(enableDebugShowRegionBoxes(bool)));
connect(ui->chkDebugTextBoxes, SIGNAL(toggled(bool)), plt->getPlotter(), SLOT(enableDebugShowTextBoxes(bool)));
}
// store JKQTPlotter plotterStyle to a temporary INI-file
// and then load that temporary file into the plainTextEdit,
@ -41,7 +45,7 @@ TestStyling::TestStyling(QWidget *parent) :
QString tmpfn=QDir::tempPath()+"/jkqtplotter_config.tmp";
{
QSettings settings(tmpfn, QSettings::IniFormat);
ui->plot->saveCurrentPlotterStyle(settings);
ui->plot1->saveCurrentPlotterStyle(settings);
}
on_btnLoad_clicked(tmpfn);
QFile::remove(tmpfn);
@ -53,7 +57,6 @@ TestStyling::~TestStyling()
if (!plotExtra.isNull()) {
plotExtra->close();
plotExtra.clear();
plotExtra->setWindowTitle("2: symbols/lines");
}
}
@ -73,9 +76,11 @@ void TestStyling::on_btnUpdate_clicked()
}
{
QSettings settings(tmpfn, QSettings::IniFormat);
ui->plot->loadCurrentPlotterStyle(settings);
for (auto plt: plots) {
plt->loadCurrentPlotterStyle(settings);
}
initPlot();
ui->chkDebugBoxes->setChecked(ui->plot->getPlotter()->isDebugShowRegionBoxesEnabled());
ui->chkDebugBoxes->setChecked(ui->plot1->getPlotter()->isDebugShowRegionBoxesEnabled());
}
QFile::remove(tmpfn);
QApplication::restoreOverrideCursor();
@ -112,9 +117,9 @@ void TestStyling::on_btnSave_clicked()
QTextStream out(&data);
out << ui->plainTextEdit->toPlainText();
}
QPixmap img=ui->plot->grab();
QPixmap img=ui->plot1->grab();
img.save(fn+".png", "png");
ui->plot->saveImage(fn+".export.png", false);
ui->plot1->saveImage(fn+".export.png", false);
}
}
@ -123,221 +128,30 @@ void TestStyling::on_btnSave_clicked()
void TestStyling::initPlot()
{
ui->plot->setPlotUpdateEnabled(false);
// 0. get a pointer to the internal datastore (for convenience)
JKQTPDatastore* ds=ui->plot->getDatastore();
// 1. clear old graphs/data
ui->plot->clearGraphs(true);
ds->clear();
// 2. now we create data for a simple plot (a sine curve)
QVector<double> X, Y1, Y2, img, X3, Y3, Y3err, Xbar, Ybar, Ybar2, Y4, Y5, XImp, YImp;
const int Ndata=100;
for (int i=0; i<Ndata; i++) {
const double x=double(i)/double(Ndata)*8.0*JKQTPSTATISTICS_PI;
X<<x;
Y1<<1.1+sin(x);
Y2<<1.1+sin(x)*exp(-0.2*x);
Y4<<4.5*exp(-x/10.0);
Y5<<2.5*exp(-x/10.0)+1.0;
if (i%5==0) {
X3<<x;
Y3<<(2.5+Y1.last());
Y3err<<(double(i+5)/double(Ndata)*0.5);
}
if (i>0 && i%20==0) {
Xbar<<x/2.0;
Ybar<<(double(i+5)/double(Ndata)*(-1.5));
Ybar2<<(double(i+5)/double(Ndata)*(-1.2));
}
if (i%8==0) {
XImp<<15.0+x/3.0;
YImp<<-1.0+0.5*sin(x);
}
}
auto fgauss=[](double x, double y, double x0, double y0, double sx, double sy) {
return exp(-2.0*(x-x0)*(x-x0)/sx/sx-2.0*(y-y0)*(y-y0)/sy/sy);
};
for (int i=0; i<Ndata; i++) {
for (int j=0; j<Ndata; j++) {
img.push_back(fgauss(j,i,Ndata/3,Ndata/3,Ndata/5,Ndata/3)+fgauss(j,i,Ndata*3/4,Ndata*2/3,Ndata/2,Ndata/4));
}
for (auto plt: plots) {
plt->setPlotUpdateEnabled(true);
plt->redrawPlot();
plt->setPlotUpdateEnabled(false);
}
// 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), so you can
// reuse X and Y afterwards!
// 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, "x");
size_t columnY1=ds->addCopiedColumn(Y1, "y1");
size_t columnY2=ds->addCopiedColumn(Y2, "y2");
size_t columnImg=ds->addCopiedColumn(img, "img");
size_t columnX3=ds->addCopiedColumn(X3, "x3");
size_t columnY3=ds->addCopiedColumn(Y3, "y3");
size_t columnY3err=ds->addCopiedColumn(Y3err, "y3err");
size_t columnXbar=ds->addCopiedColumn(Xbar, "xbar");
size_t columnYbar=ds->addCopiedColumn(Ybar, "ybar");
size_t columnYbar2=ds->addCopiedColumn(Ybar2, "Ybar2");
size_t columnY4=ds->addCopiedColumn(Y4, "y4");
size_t columnY5=ds->addCopiedColumn(Y5, "y5");
size_t columnXImp=ds->addCopiedColumn(XImp, "ximp");
size_t columnYImp=ds->addCopiedColumn(YImp, "yimp");
buildPlots(bplots);
// 4. create diverse graphs in the plot:
JKQTPFilledCurveXGraph* graphf4=new JKQTPFilledCurveXGraph(ui->plot);
graphf4->setXColumn(columnX);
graphf4->setYColumn(columnY4);
graphf4->setTitle(QObject::tr("filled exp-function"));
ui->plot->addGraph(graphf4);
JKQTPFilledCurveXGraph* graphf5=new JKQTPFilledCurveXGraph(ui->plot);
graphf5->setXColumn(columnX);
graphf5->setYColumn(columnY5);
graphf5->setTitle(QObject::tr("other filled exp-function"));
ui->plot->addGraph(graphf5);
JKQTPColumnMathImage* graphI=new JKQTPColumnMathImage(ui->plot);
graphI->setImageColumn(columnImg);
graphI->setNx(Ndata);
graphI->setNy(Ndata);
graphI->setColorBarTopVisible(true);
graphI->setColorBarRightVisible(true);
graphI->setX(0.5);
graphI->setY(-2.0);
graphI->setWidth(5);
graphI->setHeight(1);
graphI->setTitle(QObject::tr("2{\\times}Gauss"));
ui->plot->addGraph(graphI);
JKQTPXYLineGraph* graph1=new JKQTPXYLineGraph(ui->plot);
graph1->setXColumn(columnX);
graph1->setYColumn(columnY1);
graph1->setTitle(QObject::tr("sine graph $f(x)=\\sin(x)$"));
ui->plot->addGraph(graph1);
JKQTPXYLineGraph* graph2=new JKQTPXYLineGraph(ui->plot);
graph2->setXColumn(columnX);
graph2->setYColumn(columnY2);
graph2->setSymbolType(JKQTPNoSymbol);
//graph2->setTitle(QObject::tr("sine{\\cdot}exp graph $f(x)=\\sin(x)\\cdot\\exp\\left(-\\frac{x}{5}\\right)$"));
graph2->setTitle(QObject::tr("sine*exp graph"));
ui->plot->addGraph(graph2);
JKQTPXYLineErrorGraph* graph3=new JKQTPXYLineErrorGraph(ui->plot);
graph3->setXColumn(columnX3);
graph3->setYColumn(columnY3);
graph3->setYErrorColumn(columnY3err);
graph3->setDrawLine(true);
graph3->setYErrorStyle(JKQTPErrorBarsPolygons);
graph3->setTitle(QObject::tr("sine \\pm errors graph"));
ui->plot->addGraph(graph3);
JKQTPBarVerticalGraph* graphb=new JKQTPBarVerticalGraph(ui->plot);
graphb->setXColumn(columnXbar);
graphb->setYColumn(columnYbar);
graphb->setTitle(QObject::tr("barchart"));
ui->plot->addGraph(graphb);
JKQTPBarVerticalGraph* graphb2=new JKQTPBarVerticalGraph(ui->plot);
graphb2->setXColumn(columnXbar);
graphb2->setYColumn(columnYbar2);
graphb2->setTitle(QObject::tr("2^{nd} barchart"));
ui->plot->addGraph(graphb2);
graphb2->autoscaleBarWidthAndShiftSeparatedGroups();
JKQTPImpulsesVerticalGraph* graphi2=new JKQTPImpulsesVerticalGraph(ui->plot);
graphi2->setXColumn(columnXImp);
graphi2->setYColumn(columnYImp);
graphi2->setTitle(QObject::tr("impulses"));
ui->plot->addGraph(graphi2);
JKQTPBoxplotHorizontalElement* graphBP=new JKQTPBoxplotHorizontalElement(ui->plot);
graphBP->setData(-2, 7, 10,12,13,17,22);
ui->plot->addGraph(graphBP);
JKQTPGeoSymbol* annotSym=new JKQTPGeoSymbol(ui->plot, 15, -3);
ui->plot->addGraph(annotSym);
JKQTPGeoText* annotTxt=new JKQTPGeoText(ui->plot, 15.1, -3, "Annotation $\\int_{0}^{2\\pi}\\sin(x)\\;\\mathrm{d}x$");
ui->plot->addGraph(annotTxt);
JKQTPGeoEllipse* geoEll=new JKQTPGeoEllipse(ui->plot, 5,-3,5,1);
geoEll->setAngle(-25);
ui->plot->addGraph(geoEll);
ui->plot->addGraph(new JKQTPGeoArrow(ui->plot, 5,-3,10,-3.5));
ui->plot->addGraph(new JKQTPGeoLine(ui->plot, 5,-3,10,-4));
// 6. autoscale the plot so the graph is contained
ui->plot->zoomToFit();
ui->plot->getPlotter()->setPlotLabel("Sine Plots - User-Interaction Example");
ui->plot->getXAxis()->setAxisLabel("x-axis");
ui->plot->getYAxis()->setAxisLabel("y-axis");
ui->plot->setPlotUpdateEnabled(true);
ui->plot->redrawPlot();
for (auto plt: plots) {
plt->setPlotUpdateEnabled(true);
plt->redrawPlot();
}
if (!plotExtra) {
plotExtra=new JKQTPlotter;
plotExtra->setWindowTitle("2: symbols/lines");
plotExtra->show();
plotExtra->resize(width(),300);
plotExtra->move(pos().x(), pos().y()+height()+32);
}
plotExtra->setPlotUpdateEnabled(false);
plotExtra->clearGraphs(true);
plotExtra->getPlotter()->setBackgroundColor(ui->plot->getPlotter()->getBackgroundColor());
plotExtra->getPlotter()->setExportBackgroundColor(ui->plot->getPlotter()->getExportBackgroundColor());
plotExtra->getPlotter()->setPlotBackgroundColor(ui->plot->getPlotter()->getPlotBackgroundColor());
plotExtra->getXAxis()->setDrawMode1(JKQTPCADMnone);
plotExtra->getXAxis()->setDrawMode2(JKQTPCADMnone);
plotExtra->getYAxis()->setDrawMode1(JKQTPCADMnone);
plotExtra->getYAxis()->setDrawMode2(JKQTPCADMnone);
double x=1;
double xlineend=6;
double y=1;
double xmax=15;
int cnt=0;
for (auto s: ui->plot->getPlotter()->getCurrentPlotterStyle().graphsStyle.defaultGraphSymbols) {
plotExtra->addGraph(new JKQTPGeoSymbol(plotExtra.data(), x, y, s, 12, QColor("red"), QColor("salmon") ));
x+=1;
xmax=qMax(x, xmax);
if (cnt>0 && cnt%25==0) {
x=1;
y+=1.0;
}
cnt++;
}
y=y+1;
double ycoltest=y;
for (auto s: ui->plot->getPlotter()->getCurrentPlotterStyle().graphsStyle.defaultGraphPenStyles) {
JKQTPGeoLine* l;
plotExtra->addGraph(l=new JKQTPGeoLine(plotExtra.data(), 1,y,xlineend,y)); l->setStyle(QColor("red"), 2, s);
plotExtra->addGraph(l=new JKQTPGeoLine(plotExtra.data(), 1,y-0.25,xlineend,y-0.25)); l->setStyle(QColor("maroon"), 1, s);
y+=0.75;
}
x=xlineend+1;
const int cntFillTests=qMax(ui->plot->getPlotter()->getCurrentPlotterStyle().graphsStyle.defaultGraphColors.size(), ui->plot->getPlotter()->getCurrentPlotterStyle().graphsStyle.defaultGraphFillStyles.size());
double dx=(xmax-xlineend-1.0)/static_cast<double>(cntFillTests);
for (int i=0; i<cntFillTests; i++) {
const auto col=ui->plot->getPlotter()->getCurrentPlotterStyle().graphsStyle.defaultGraphColors.value(i%ui->plot->getPlotter()->getCurrentPlotterStyle().graphsStyle.defaultGraphColors.size(), Qt::black);
const auto fs=ui->plot->getPlotter()->getCurrentPlotterStyle().graphsStyle.defaultGraphFillStyles.value(i%ui->plot->getPlotter()->getCurrentPlotterStyle().graphsStyle.defaultGraphFillStyles.size(), Qt::SolidPattern);
JKQTPGeoLine* l;
plotExtra->addGraph(l=new JKQTPGeoLine(plotExtra.data(), x,ycoltest,x,y-0.5)); l->setStyle(col,5);
JKQTPGeoRectangle* r;
plotExtra->addGraph(r=new JKQTPGeoRectangle(plotExtra.data(), x+dx/2,(ycoltest+y-0.5)/2.0, dx*0.5, y-ycoltest-0.5));
r->setStyle(col,1, Qt::SolidLine, JKQTPGetDerivedColor(ui->plot->getPlotter()->getCurrentPlotterStyle().graphsStyle.defaultGraphStyle.fillColorDerivationMode, col), fs);
x+=dx;
}
plotExtra->zoomToFit();
plotExtra->setX(0, plotExtra->getXMax()+2);
plotExtra->setY(0, plotExtra->getYMax()+1);
plotExtra->setGrid(false);
plotExtra->getPlotter()->setPlotLabel("default symbols/lines/colors");
buildLineSymbolSampler(plotExtra->getPlotter(), bplots[0]);
plotExtra->setPlotUpdateEnabled(true);
plotExtra->redrawPlot();
}

View File

@ -27,6 +27,8 @@ class TestStyling : public QMainWindow
Ui::TestStyling *ui;
void initPlot();
QPointer<JKQTPlotter> plotExtra;
QVector<JKQTPlotter*> plots;
QVector<JKQTBasePlotter*> bplots;
};
#endif // TEST_STYLING_H

View File

@ -6,21 +6,65 @@
<rect>
<x>0</x>
<y>0</y>
<width>1068</width>
<height>691</height>
<width>1547</width>
<height>976</height>
</rect>
</property>
<property name="windowTitle">
<string>1: Tutorial/TestApp: JKQTPlotter Styling</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="JKQTPlotter" name="plot" native="true"/>
<property name="childrenCollapsible">
<bool>false</bool>
</property>
<widget class="QWidget" name="layoutWidget_2" native="true">
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="2">
<widget class="JKQTPlotter" name="plot7" native="true"/>
</item>
<item row="0" column="1">
<widget class="JKQTPlotter" name="plot2" native="true">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="JKQTPlotter" name="plot3" native="true"/>
</item>
<item row="1" column="1">
<widget class="JKQTPlotter" name="plot6" native="true"/>
</item>
<item row="0" column="0">
<widget class="JKQTPlotter" name="plot1" native="true">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="JKQTPlotter" name="plot5" native="true"/>
</item>
<item row="0" column="3">
<widget class="JKQTPlotter" name="plot4" native="true"/>
</item>
<item row="1" column="3">
<widget class="JKQTPlotter" name="plot8" native="true"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@ -219,8 +263,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1068</width>
<height>17</height>
<width>1547</width>
<height>22</height>
</rect>
</property>
</widget>

View File

@ -10,12 +10,14 @@ message( STATUS ".. Building Tool ${EXAMPLE_NAME}" )
set(SOURCES
${EXAMPLE_NAME}.cpp
)
set(HEADERS )
set(HEADERS
${CMAKE_CURRENT_LIST_DIR}/../../examples/styling/build_test_graphs.h
)
set(RESOURCES )
set(UIS )
add_executable(${EXENAME} WIN32 ${SOURCES} ${HEADERS} ${RESOURCES} ${UIS})
target_include_directories(${EXENAME} PRIVATE ../../lib)
target_include_directories(${EXENAME} PRIVATE ../../lib ${CMAKE_CURRENT_LIST_DIR}/../../examples/styling/)
if(JKQtPlotter_BUILD_STATIC_LIBS)
target_link_libraries(${EXENAME} JKQTPlotterLib)
elseif(JKQtPlotter_BUILD_SHARED_LIBS)

View File

@ -15,6 +15,7 @@
#include <QTextStream>
#include <algorithm>
#include <QDateTime>
#include <QVector>
#if (QT_VERSION>=QT_VERSION_CHECK(6, 0, 0))
#include<QRegularExpression>
#include<QRegularExpressionMatch>
@ -25,15 +26,7 @@
#include "jkqtcommon/jkqtpdrawingtools.h"
#include "jkqtcommon/jkqtpenhancedpainter.h"
#include "jkqtplotter/jkqtpbaseplotter.h"
#include "jkqtplotter/graphs/jkqtplines.h"
#include "jkqtplotter/graphs/jkqtpscatter.h"
#include "jkqtplotter/graphs/jkqtpbarchart.h"
#include "jkqtplotter/graphs/jkqtpimage.h"
#include "jkqtplotter/graphs/jkqtpgeometric.h"
#include "jkqtplotter/graphs/jkqtpgeoannotations.h"
#include "jkqtplotter/graphs/jkqtpboxplot.h"
#include "jkqtplotter/graphs/jkqtpfilledcurve.h"
#include "jkqtplotter/graphs/jkqtpimpulses.h"
#include "build_test_graphs.h"
#include <iostream>
#if __cplusplus >= 202002L
# include <version>
@ -55,6 +48,21 @@ void startPainting(QImage& img, JKQTPEnhancedPainter& p, int iconsize, QColor ba
startPainting(img, p, iconsize,iconsize,backgroundColor);
}
void startPaintingChecker(QImage& img, JKQTPEnhancedPainter& p, int iconsizex, int iconsizey, int check_size, QColor backgroundColor1, QColor backgroundColor2) {
img=QImage(QSize(iconsizex,iconsizey),QImage::Format_ARGB32_Premultiplied);
img.fill(backgroundColor1);
p.begin(&img);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::TextAntialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
for (int y=0; y<iconsizey+check_size; y+=check_size*2) {
for (int x=0; x<iconsizex+check_size; x+=check_size*2) {
p.fillRect(x,y,check_size,check_size,backgroundColor2);
p.fillRect(x+check_size,y+check_size,check_size,check_size,backgroundColor2);
}
}
}
void stopPaintingAndSave(QImage& img, JKQTPEnhancedPainter& p, const QString& filename) {
p.end();
@ -127,6 +135,18 @@ void doListLineDecorators(const QDir& outputDir, int iconsize, QColor background
}
}
void doListPalettes(const QDir& outputDir, QSize iconsize) {
for (uint64_t i=0; i<JKQTPMathImagePREDEFINED_PALETTES_COUNT; i++) {
const JKQTPMathImageColorPalette s=static_cast<JKQTPMathImageColorPalette>(i);
QImage img;
JKQTPEnhancedPainter p;
startPaintingChecker(img, p, iconsize.width(),iconsize.height(), iconsize.height()/6, QColor("white"), QColor("silver"));
p.drawImage(0,0,JKQTPImageTools::GetPaletteImage(i,iconsize.width(), iconsize.height()));
stopPaintingAndSave(img, p, outputDir.absoluteFilePath("palette_"+JKQTPImageTools::JKQTPMathImageColorPalette2String(s)+".png"));
}
}
void doListErrorIndicators(const QDir& outputDir, int iconsize, QColor backgroundColor) {
JKQTBasePlotter plot(true);
@ -389,221 +409,39 @@ void doListAxisStyling(const QDir& outputDir, int iconsize, QColor backgroundCol
plot.grabPixelImage(QSize(plot.getWidth(),plot.getHeight()), false).copy(0,0,plot.getWidth(),plot.getHeight()).save(outputDir.absoluteFilePath("axis_unit_scaling_pi.png"), "png");
}
void plotStyle(JKQTBasePlotter& plot) {
void plotStyle(const QSettings& style, QSize examplePlotSize, const QString& examplePlotFilename, QSize samplePlotSize, const QString& samplePlotFilename ) {
JKQTBasePlotter plotExtra(true);
// 0. get a pointer to the internal datastore (for convenience)
JKQTPDatastore* ds=plot.getDatastore();
// 1. clear old graphs/data
plot.clearGraphs(true);
ds->clear();
// 2. now we create data for a simple plot (a sine curve)
QVector<double> X, Y1, Y2, img, X3, Y3, Y3err, Xbar, Ybar, Ybar2, Y4, Y5, XImp, YImp;
const int Ndata=100;
for (int i=0; i<Ndata; i++) {
const double x=double(i)/double(Ndata)*8.0*JKQTPSTATISTICS_PI;
X<<x;
Y1<<1.1+sin(x);
Y2<<1.1+sin(x)*exp(-0.2*x);
Y4<<4.5*exp(-x/10.0);
Y5<<2.5*exp(-x/10.0)+1.0;
if (i%5==0) {
X3<<x;
Y3<<(2.5+Y1.last());
Y3err<<(double(i+5)/double(Ndata)*0.5);
}
if (i>0 && i%20==0) {
Xbar<<x/2.0;
Ybar<<(double(i+5)/double(Ndata)*(-1.5));
Ybar2<<(double(i+5)/double(Ndata)*(-1.2));
}
if (i%8==0) {
XImp<<15.0+x/3.0;
YImp<<-1.0+0.5*sin(x);
QVector<JKQTBasePlotter*> plots;
for (int x=0; x<DEFAULT_PLOT_SIZE.width(); x++) {
for (int y=0; y<DEFAULT_PLOT_SIZE.height(); y++) {
if (x==0 && y==0) {
plots<<new JKQTBasePlotter(true);
} else {
plots<<new JKQTBasePlotter(false, nullptr, plots.first()->getDatastore());
}
}
}
auto fgauss=[](double x, double y, double x0, double y0, double sx, double sy) {
return exp(-2.0*(x-x0)*(x-x0)/sx/sx-2.0*(y-y0)*(y-y0)/sy/sy);
};
for (int i=0; i<Ndata; i++) {
for (int j=0; j<Ndata; j++) {
img.push_back(fgauss(j,i,Ndata/3,Ndata/3,Ndata/5,Ndata/3)+fgauss(j,i,Ndata*3/4,Ndata*2/3,Ndata/2,Ndata/4));
}
for (auto p: plots) {
p->loadCurrentPlotterStyle(style);
p->setWidgetSize(QSize(examplePlotSize.width()/DEFAULT_PLOT_SIZE.width(),examplePlotSize.height()/DEFAULT_PLOT_SIZE.height()));
}
plotExtra.setWidgetSize(samplePlotSize);
setupGridPrintingAndDatastores(plots, DEFAULT_PLOT_SIZE);
buildPlots(plots);
buildLineSymbolSampler(&plotExtra, plots.first());
// 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), so you can
// reuse X and Y afterwards!
// 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, "x");
size_t columnY1=ds->addCopiedColumn(Y1, "y1");
size_t columnY2=ds->addCopiedColumn(Y2, "y2");
size_t columnImg=ds->addCopiedColumn(img, "img");
size_t columnX3=ds->addCopiedColumn(X3, "x3");
size_t columnY3=ds->addCopiedColumn(Y3, "y3");
size_t columnY3err=ds->addCopiedColumn(Y3err, "y3err");
size_t columnXbar=ds->addCopiedColumn(Xbar, "xbar");
size_t columnYbar=ds->addCopiedColumn(Ybar, "ybar");
size_t columnYbar2=ds->addCopiedColumn(Ybar2, "Ybar2");
size_t columnY4=ds->addCopiedColumn(Y4, "y4");
size_t columnY5=ds->addCopiedColumn(Y5, "y5");
size_t columnXImp=ds->addCopiedColumn(XImp, "ximp");
size_t columnYImp=ds->addCopiedColumn(YImp, "yimp");
//QSize(examplePlotSize.width()*DEFAULT_PLOT_SIZE.width(),examplePlotSize.height()*DEFAULT_PLOT_SIZE.height())
plots.first()->grabPixelImage(examplePlotSize, false).save(examplePlotFilename);
//plots.first()->saveAsPixelImage(examplePlotFilename, false);
plotExtra.grabPixelImage(samplePlotSize, false).save(samplePlotFilename);
// 4. create diverse graphs in the plot:
JKQTPFilledCurveXGraph* graphf4=new JKQTPFilledCurveXGraph(&plot);
graphf4->setXColumn(columnX);
graphf4->setYColumn(columnY4);
graphf4->setTitle(QObject::tr("filled exp-function"));
plot.addGraph(graphf4);
JKQTPFilledCurveXGraph* graphf5=new JKQTPFilledCurveXGraph(&plot);
graphf5->setXColumn(columnX);
graphf5->setYColumn(columnY5);
graphf5->setTitle(QObject::tr("other filled exp-function"));
plot.addGraph(graphf5);
JKQTPColumnMathImage* graphI=new JKQTPColumnMathImage(&plot);
graphI->setImageColumn(columnImg);
graphI->setNx(Ndata);
graphI->setNy(Ndata);
graphI->setColorBarTopVisible(true);
graphI->setColorBarRightVisible(true);
graphI->setX(0.5);
graphI->setY(-2.0);
graphI->setWidth(5);
graphI->setHeight(1);
graphI->setTitle(QObject::tr("2{\\times}Gauss"));
plot.addGraph(graphI);
JKQTPXYLineGraph* graph1=new JKQTPXYLineGraph(&plot);
graph1->setXColumn(columnX);
graph1->setYColumn(columnY1);
graph1->setTitle(QObject::tr("sine graph $f(x)=\\sin(x)$"));
plot.addGraph(graph1);
JKQTPXYLineGraph* graph2=new JKQTPXYLineGraph(&plot);
graph2->setXColumn(columnX);
graph2->setYColumn(columnY2);
graph2->setSymbolType(JKQTPNoSymbol);
//graph2->setTitle(QObject::tr("sine{\\cdot}exp graph $f(x)=\\sin(x)\\cdot\\exp\\left(-\\frac{x}{5}\\right)$"));
graph2->setTitle(QObject::tr("sine*exp graph"));
plot.addGraph(graph2);
JKQTPXYLineErrorGraph* graph3=new JKQTPXYLineErrorGraph(&plot);
graph3->setXColumn(columnX3);
graph3->setYColumn(columnY3);
graph3->setYErrorColumn(columnY3err);
graph3->setDrawLine(true);
graph3->setYErrorStyle(JKQTPErrorBarsPolygons);
graph3->setTitle(QObject::tr("sine \\pm errors graph"));
plot.addGraph(graph3);
JKQTPBarVerticalGraph* graphb=new JKQTPBarVerticalGraph(&plot);
graphb->setXColumn(columnXbar);
graphb->setYColumn(columnYbar);
graphb->setTitle(QObject::tr("barchart"));
plot.addGraph(graphb);
JKQTPBarVerticalGraph* graphb2=new JKQTPBarVerticalGraph(&plot);
graphb2->setXColumn(columnXbar);
graphb2->setYColumn(columnYbar2);
graphb2->setTitle(QObject::tr("2^{nd} barchart"));
plot.addGraph(graphb2);
graphb2->autoscaleBarWidthAndShiftSeparatedGroups();
JKQTPImpulsesVerticalGraph* graphi2=new JKQTPImpulsesVerticalGraph(&plot);
graphi2->setXColumn(columnXImp);
graphi2->setYColumn(columnYImp);
graphi2->setTitle(QObject::tr("impulses"));
plot.addGraph(graphi2);
JKQTPBoxplotHorizontalElement* graphBP=new JKQTPBoxplotHorizontalElement(&plot);
graphBP->setData(-2, 7, 10,12,13,17,22);
plot.addGraph(graphBP);
JKQTPGeoSymbol* annotSym=new JKQTPGeoSymbol(&plot, 15, -3);
plot.addGraph(annotSym);
JKQTPGeoText* annotTxt=new JKQTPGeoText(&plot, 15.1, -3, "Annotation $\\int_{0}^{2\\pi}\\sin(x)\\;\\mathrm{d}x$");
plot.addGraph(annotTxt);
JKQTPGeoEllipse* geoEll=new JKQTPGeoEllipse(&plot, 5,-3,5,1);
geoEll->setAngle(-25);
plot.addGraph(geoEll);
plot.addGraph(new JKQTPGeoArrow(&plot, 5,-3,10,-3.5));
plot.addGraph(new JKQTPGeoLine(&plot, 5,-3,10,-4));
// 6. autoscale the plot so the graph is contained
plot.zoomToFit();
plot.setPlotLabel("Sine Plots - User-Interaction Example");
plot.getXAxis()->setAxisLabel("x-axis");
plot.getYAxis()->setAxisLabel("y-axis");
plot.redrawPlot();
for (int i=plots.size()-1; i>=0; i--) {
delete plots[i];
}
}
void plotStyleSymbols(JKQTBasePlotter& plotExtra, const JKQTBasePlotter& plot) {
plotExtra.clearGraphs(true);
plotExtra.setBackgroundColor(plot.getBackgroundColor());
plotExtra.setExportBackgroundColor(plot.getExportBackgroundColor());
plotExtra.setPlotBackgroundColor(plot.getPlotBackgroundColor());
plotExtra.getXAxis()->setDrawMode1(JKQTPCADMnone);
plotExtra.getXAxis()->setDrawMode2(JKQTPCADMnone);
plotExtra.getYAxis()->setDrawMode1(JKQTPCADMnone);
plotExtra.getYAxis()->setDrawMode2(JKQTPCADMnone);
double x=1;
double xlineend=6;
double y=1;
double xmax=15;
int cnt=0;
for (auto s: plot.getCurrentPlotterStyle().graphsStyle.defaultGraphSymbols) {
plotExtra.addGraph(new JKQTPGeoSymbol(&plotExtra, x, y, s, 12 ));
const auto col=plot.getCurrentPlotterStyle().graphsStyle.defaultGraphColors.value(0, Qt::black);
dynamic_cast<JKQTPGeoSymbol*>(plotExtra.getGraph(cnt))->setSymbolColor(col);
dynamic_cast<JKQTPGeoSymbol*>(plotExtra.getGraph(cnt))->setSymbolFillColor(col);
x+=1;
xmax=qMax(x, xmax);
if (cnt>0 && cnt%25==0) {
x=1;
y+=1.0;
}
cnt++;
}
y=y+1;
double ycoltest=y;
for (auto s: plot.getCurrentPlotterStyle().graphsStyle.defaultGraphPenStyles) {
JKQTPGeoLine* l;
plotExtra.addGraph(l=new JKQTPGeoLine(&plotExtra, 1,y,xlineend,y)); l->setStyle(QColor("red"), 2, s);
const auto col=plot.getCurrentPlotterStyle().graphsStyle.defaultGraphColors.value(0, Qt::black);
dynamic_cast<JKQTPGeoLine*>(plotExtra.getGraph(cnt))->setLineColor(col);
y+=0.75;
}
x=xlineend+1;
const int cntFillTests=qMax(plot.getCurrentPlotterStyle().graphsStyle.defaultGraphColors.size(), plot.getCurrentPlotterStyle().graphsStyle.defaultGraphFillStyles.size());
double dx=(xmax-xlineend-1.0)/static_cast<double>(cntFillTests);
for (int i=0; i<cntFillTests; i++) {
const auto col=plot.getCurrentPlotterStyle().graphsStyle.defaultGraphColors.value(i%plot.getCurrentPlotterStyle().graphsStyle.defaultGraphColors.size(), Qt::black);
const auto fs=plot.getCurrentPlotterStyle().graphsStyle.defaultGraphFillStyles.value(i%plot.getCurrentPlotterStyle().graphsStyle.defaultGraphFillStyles.size(), Qt::SolidPattern);
JKQTPGeoLine* l;
plotExtra.addGraph(l=new JKQTPGeoLine(&plotExtra, x,ycoltest,x,y-0.5)); l->setStyle(col,5);
JKQTPGeoRectangle* r;
plotExtra.addGraph(r=new JKQTPGeoRectangle(&plotExtra, x+dx/2,(ycoltest+y-0.5)/2.0, dx*0.5, y-ycoltest-0.5));
r->setStyle(col,1, Qt::SolidLine, JKQTPGetDerivedColor(plot.getCurrentPlotterStyle().graphsStyle.defaultGraphStyle.fillColorDerivationMode, col), fs);
x+=dx;
}
plotExtra.zoomToFit();
plotExtra.setX(0, plotExtra.getXMax()+2);
plotExtra.setY(0, plotExtra.getYMax()+1);
plotExtra.setGrid(false);
plotExtra.setPlotLabel("default symbols/lines/colors");
plotExtra.redrawPlot();
}
void doListStyles(const QDir& outputDir, const QStringList& doctomodify, int iconsize, QColor backgroundColor) {
@ -612,19 +450,17 @@ void doListStyles(const QDir& outputDir, const QStringList& doctomodify, int ico
{
QTextStream shtml(&doc);
shtml<<"<table>\n <tr>\n <th>Style-file\n <th>Screenshot\n <th>Symbols\n";
for (auto& f: dir.entryList()) {
auto files=dir.entryList();
if (files.indexOf("default.ini")>=0) {
files.swapItemsAt(0,files.indexOf("default.ini"));
}
for (auto& f: files) {
qDebug()<<"plotting example for style "<<f;
JKQTBasePlotter plot(true);
plot.setWidgetSize(iconsize,iconsize);
plot.loadCurrentPlotterStyle(QSettings(dir.absoluteFilePath(f), QSettings::IniFormat));
plotStyle(plot);
plot.grabPixelImage(QSize(plot.getWidth(),plot.getHeight()), false).copy(0,0,plot.getWidth(),plot.getHeight()).save(outputDir.absoluteFilePath(f+".png"), "png");
JKQTBasePlotter plotExtra(true);
plotExtra.setWidgetSize(iconsize*2, iconsize/3);
plotStyleSymbols(plotExtra, plot);
plotExtra.grabPixelImage(QSize(plotExtra.getWidth(),plotExtra.getHeight()), false).copy(0,0,plotExtra.getWidth(),plotExtra.getHeight()).save(outputDir.absoluteFilePath(f+".symbols.png"), "png");
plotStyle(QSettings(dir.absoluteFilePath(f), QSettings::IniFormat),
QSize(iconsize,iconsize*DEFAULT_PLOT_SIZE.height()/DEFAULT_PLOT_SIZE.width()), outputDir.absoluteFilePath(f+".png"),
QSize(iconsize/3*2, iconsize/3*2/2), outputDir.absoluteFilePath(f+".symbols.png"));
shtml<<" <tr>\n"
<<" <td><a href=\"https://github.com/jkriege2/JKQtPlotter/tree/master/lib/jkqtplotter/resources/styles/"<<f<<"\"><code>"<<dir.absoluteFilePath(f)<<"</code></a>\n"
@ -677,6 +513,8 @@ int main(int argc, char* argv[])
parser.addOption(listerrorindicatorsOption);
QCommandLineOption listaxisstylepropsOption("listaxisstyleprops", "generate example images for JKQTPCALabelType and other coordinate axis properties.");
parser.addOption(listaxisstylepropsOption);
QCommandLineOption listpalettesOption("listpalettes", "generate example images for all predefined palettes.");
parser.addOption(listpalettesOption);
QCommandLineOption liststylesOption("liststyles", "generate example images for all predefined style INI files.");
parser.addOption(liststylesOption);
QCommandLineOption iconsizeOption("iconsize", "typical size of the generatued images.", "iconsize", "24");
@ -688,6 +526,7 @@ int main(int argc, char* argv[])
const QDir outputDir(parser.value(outputDirectoryOption));
const QStringList doctomodify(parser.value(doctomodifyectoryOption).split(","));
const bool listsymbols=parser.isSet(listsymbolsOption);
const bool listpalettes=parser.isSet(listpalettesOption);
const bool listlinedecorators=parser.isSet(listlinedecoratorsOption);
const bool listerrorindicators=parser.isSet(listerrorindicatorsOption);
const bool listaxisstyleprops=parser.isSet(listaxisstylepropsOption);
@ -702,6 +541,7 @@ int main(int argc, char* argv[])
if (listerrorindicators) doListErrorIndicators(outputDir, iconsize, backgroundColor);
if (listaxisstyleprops) doListAxisStyling(outputDir, iconsize, backgroundColor);
if (liststyles) doListStyles(outputDir, doctomodify, iconsize, backgroundColor);
if (listpalettes) doListPalettes(outputDir, QSize(iconsize,qMax(5,iconsize/16)));
return EXIT_SUCCESS;
}