JKQtPlotter/examples/scatter_customsymbol
jkriege2 b0df7a1fd7 NEW/BREAKING: provide general targets JKQTPlotter5/6::JKQTPlotter5/6, JKQTPlotter5/6::JKQTMathText5/6, ... which are independent of the type of build (shared/static)
NEW/BREAKING: refactor CMake-Code, so static/dynamic switch is done via <code>BUILD_SHARED_LIBS</code>, which retires <code>JKQtPlotter_BUILD_STATIC_LIBS</code>, <code>JKQtPlotter_BUILD_SHARED_LIBS</code> and removes the capability to build static and shared libraries in one location (fixes issue #104)
NEW: prepareed library for CMake's <a href="https://cmake.org/cmake/help/latest/module/FetchContent.html">FetchContent</a>-API
NEW: the different sub-libraries JKQTPlotter, JKQTFastPlotter (DEPRECATED), JKQTMath, JKQTMathText can be activated/deactivated with CMake options JKQtPlotter_BUILD_LIB_JKQTPLOTTER, JKQtPlotter_BUILD_LIB_JKQTFASTPLOTTER, JKQtPlotter_BUILD_LIB_JKQTMATHTEXT, JKQtPlotter_BUILD_LIB_JKQTMATH
2024-01-16 13:07:08 +01:00
..
CMakeLists.txt NEW/BREAKING: provide general targets JKQTPlotter5/6::JKQTPlotter5/6, JKQTPlotter5/6::JKQTMathText5/6, ... which are independent of the type of build (shared/static) 2024-01-16 13:07:08 +01:00
README.md JKQTPlotter: added examples for custom symbols 2022-09-07 21:38:29 +02:00
scatter_customsymbol.cpp JKQTPlotter: added examples for custom symbols 2022-09-07 21:38:29 +02:00

Example (JKQTPlotter): Scatter-graph with custom symbols

This project (see ./examples/scatter_customsymbol/) demonstrates using JKQTPlotter to draw a scatter graph (JKQTPXYScatterGraph) with custom symbols.

The source code of the example can be found in jkqtplotter_scatter.cpp.

First we create a plotter window and get a pointer to the internal datastore (for convenience):

    JKQTPlotter plot;
    JKQTPDatastore* ds=plot.getDatastore();

Now we add several columns to the JKQTPDatastore and obtain back-inserter iterators for these:

    size_t columnX=ds->addColumn("x");
    auto colXInserter=ds->backInserter(columnX);
    size_t columnY1=ds->addColumn("y1");
    auto colY1Inserter=ds->backInserter(columnY1);
    size_t columnY2=ds->addColumn("y2");
    auto colY2Inserter=ds->backInserter(columnY2);
    size_t columnY3=ds->addColumn("y3");
    auto colY3Inserter=ds->backInserter(columnY3);
    size_t columnY4=ds->addColumn("y4");
    auto colY4Inserter=ds->backInserter(columnY4);

... and fill the columns with data

    const int Ndata=5;
    for (int i=0; i<Ndata; i++) {
        // put data
        const double x=double(i)/double(Ndata-1);
        *(colXInserter++)=x;
        *(colY1Inserter++)=3.0+pow(x*1.3, 2.0)*1.3;
        *(colY2Inserter++)=2.0+pow(x*1.3, 2.0)*1.2;
        *(colY3Inserter++)=1.0+pow(x*1.3, 2.0)*1.1;
        *(colY4Inserter++)=pow(x*1.3, 2.0);
    }

Now we create several graph objects of type JKQTPXYScatterGraph. Each one uses a different custom symbol style:

Graphs graph3 and graph4 use JKQTPCharacterSymbol and JKQTPFilledCharacterSymbol respectively to draw spades and hearts from the unicode characters U+2660 and U+2665 respectively. The two graphs differ in the coloring of the symbols. The JKQTPCharacterSymbol variant would use the color default (cycling) graph color, but here we overwrite this with darkblue. The JKQTPFilledCharacterSymbol variant uses red filled hearts with a thin black border.

    JKQTPXYScatterGraph* graph3=new JKQTPXYScatterGraph(&plot);
    graph3->setXColumn(columnX);
    graph3->setYColumn(columnY3);
    graph3->setSymbolType(JKQTPCharacterSymbol+QChar(0x2660).unicode());
    graph3->setSymbolColor(QColor("darkblue"));
    graph3->setSymbolSize(15);
    graph3->setTitle(QObject::tr("spades"));
    plot.addGraph(graph3);

    JKQTPXYScatterGraph* graph4=new JKQTPXYScatterGraph(&plot);
    graph4->setXColumn(columnX);
    graph4->setYColumn(columnY4);
    graph4->setSymbolType(JKQTPFilledCharacterSymbol+QChar(0x2665).unicode());
    graph4->setSymbolSize(20);
    graph4->setSymbolColor(QColor("black"));
    graph4->setSymbolFillColor(QColor("red"));
    graph4->setSymbolLineWidth(0.5);
    graph4->setTitle(QObject::tr("hearts"));
    plot.addGraph(graph4);

The more advanced graphs graph1 and graph2 use JKQTPRegisterCustomGraphSymbol() to register functors that draw user-specific symbols:

    JKQTPCustomGraphSymbolFunctor f=[](QPainter& p) {
        p.setBrush(Qt::NoBrush); // ensure that circles are not drawn filled
        p.drawEllipse(QPointF(-0.33, -0.33/4.0), 0.33/2.0, 0.33/2.0);
        p.drawEllipse(QPointF(0, -0.33/4.0), 0.33/2.0, 0.33/2.0);
        p.drawEllipse(QPointF(0.33, -0.33/4.0), 0.33/2.0, 0.33/2.0);
        p.drawEllipse(QPointF(-0.33/2.0, 0.33/4.0), 0.33/2.0, 0.33/2.0);
        p.drawEllipse(QPointF(0.33/2.0, 0.33/4.0), 0.33/2.0, 0.33/2.0);
    };
    JKQTPGraphSymbols customsymbol_olympicrings=JKQTPRegisterCustomGraphSymbol(f);
    JKQTPXYScatterGraph* graph1=new JKQTPXYScatterGraph(&plot);
    graph1->setXColumn(columnX);
    graph1->setYColumn(columnY1);
    graph1->setSymbolType(customsymbol_olympicrings);
    graph1->setSymbolSize(30);
    graph1->setTitle(QObject::tr("olympics"));
    plot.addGraph(graph1);


    JKQTPGraphSymbols customsymbol_coloredolympicrings=JKQTPRegisterCustomGraphSymbol(
                [](QPainter& p) {
                        p.setBrush(Qt::NoBrush); // ensure that circles are not drawn filled
                        const double w=p.pen().widthF();
                        p.setPen(QPen(QColor("red"), w));
                        p.drawEllipse(QPointF(-0.33, -0.33/4.0), 0.33/2.0, 0.33/2.0);
                        p.setPen(QPen(QColor("black"), w));
                        p.drawEllipse(QPointF(0, -0.33/4.0), 0.33/2.0, 0.33/2.0);
                        p.setPen(QPen(QColor("gold"), w));
                        p.drawEllipse(QPointF(0.33, -0.33/4.0), 0.33/2.0, 0.33/2.0);
                        p.setPen(QPen(QColor("darkgreen"), w));
                        p.drawEllipse(QPointF(-0.33/2.0, 0.33/4.0), 0.33/2.0, 0.33/2.0);
                        p.setPen(QPen(QColor("darkblue"), w));
                        p.drawEllipse(QPointF(0.33/2.0, 0.33/4.0), 0.33/2.0, 0.33/2.0);
                    });
    JKQTPXYScatterGraph* graph2=new JKQTPXYScatterGraph(&plot);
    graph2->setXColumn(columnX);
    graph2->setYColumn(columnY2);
    graph2->setSymbolType(customsymbol_coloredolympicrings);
    graph2->setSymbolSize(30);
    graph2->setTitle(QObject::tr("colored olympics"));
    plot.addGraph(graph2);                    

Bothe variant show the olympic rings. graph1 uses the (cycling) default graph color and graph2 draws with user-defined colors.

The result looks like this:

scatter_customsymbol