From a6084bd2d614464f00661c2e10215383ee24bcb7 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 30 Mar 2024 23:45:03 +0100 Subject: [PATCH] Library: implement generation of a simple data visualisation CSV data -> Gnuplot script --- src/lib/gnuplot-gen.cpp | 127 +++++++++++++-------- tests/library/gnuplot-gen-test.cpp | 2 +- wiki/thinkPad.ichthyo.mm | 175 +++++++++++++++++++++++++---- 3 files changed, 235 insertions(+), 69 deletions(-) diff --git a/src/lib/gnuplot-gen.cpp b/src/lib/gnuplot-gen.cpp index ac5f3d3c8..3c935a15f 100644 --- a/src/lib/gnuplot-gen.cpp +++ b/src/lib/gnuplot-gen.cpp @@ -35,52 +35,28 @@ #include "lib/text-template.hpp" +#include "lib/text-template-gen-node-binding.hpp" #include "lib/gnuplot-gen.hpp" +#include "lib/format-util.hpp" #include using std::string; +using util::join; +using lib::diff::MakeRec; + namespace lib { namespace gnuplot_gen { - namespace { + + namespace { // Template and defaults definitions for diagram generation - const string GNUPLOT_SCATTER_REGRESSION = R"~(# -# -# - -set term wxt size 600,800 - -set datafile separator ",;" - -$RunData << _End_of_Data_ -"graph length";"duration (ms)";"concurrency";"job time" -49, 24.3764, 5 -5 , 4.30955, 5, 700 -32, 16.039 , 5, 740 -20, 6.47043, 4, 930 -39, 19.424 , 4, 888 -49, 15.951 , 4, 688 -51, 32.7247, 5, 1200 -62, 31.4712, 5, 812 -15, 13.552 , 4 -56, 36.1978, 4 -32, 16.4677, 5 -57, 22.2576, 6, 833 -17, 14.3244, 5, 844 -54, 27.4692, 5 -46, 12.4055 -52, 19.9593 -39, 19.4265 -41, 22.0513 -64, 33.744 -2, 3.04284 -_End_of_Data_ - - -set style line 1 linetype 1 linewidth 2 linecolor rgb '#1700D4' -set style line 2 linetype 3 linewidth 2 linecolor rgb '#113DD6' + + const string GNUPLOT_CommonStyleDef = R"~(# +#---common-styles-for-plots-from-Lumiera---- +set style line 1 linetype 1 linewidth 2 linecolor rgb '#240CC3' +set style line 2 linetype 3 linewidth 2 linecolor rgb '#1149D6' set style line 3 linetype 2 linewidth 2 linecolor rgb '#0B7FCC' set style line 4 linetype 6 linewidth 2 linecolor rgb '#37999D' set style line 5 linetype 7 linewidth 2 linecolor rgb '#248269' @@ -91,19 +67,65 @@ set style line 9 linetype 4 linewidth 2 linecolor rgb '#AA0519' set style line 10 linetype 1 linewidth 1 linecolor rgb '#303030' set style line 11 linetype 0 linewidth 1 linecolor rgb '#A0A0A0' dashtype 3 - +#---(End)styles----------------------------- +)~"; + + const string GNUPLOT_AxisGridSetup = R"~(# +#---axis-and-grid-setup--------------------- unset border set tics nomirror set grid back linestyle 11 -#set size ratio 0.6 - set arrow 10 from graph 0,0 to graph 1.04,0 size screen 0.025,15,60 filled ls 10 set arrow 11 from graph 0,0 to graph 0,1.05 size screen 0.025,15,60 filled ls 10 +)~"; + + + const string GNUPLOT_BASIC_PLOT_DEF = R"~(# +# +# GNUPLOT - data plot from Lumiera +# -set key autotitle columnheader -set x2label 'X axis' -set ylabel 'Y axis' +${if Term}set term ${Term} ${ +if TermSizeSpec}size ${TermSizeSpec}${endif}${ +endif Term} + +set datafile separator ",;" + +####---------Data--------------------------- +$RunData << _End_of_Data_ +${CSVData} +_End_of_Data_ + + +${CommonStyleDef} +${AxisGridSetup} + +${if XLabel +}set xlabel '${XLabel}' +${else +}stats $RunData using (abscissaName=strcol(1)) every ::0::0 nooutput + +set xlabel abscissaName +${end if XLabel +}${if YLabel +}set ylabel '${YLabel}' +${end if YLabel +} +set key autotitle columnheader tmargin + +)~"; + + const string GNUPLOT_SIMPLE_DATA_PLOT = R"~(# +####---------------------------------------- +plot for [i=2:*] $RunData using 1:i with ${DiagramKind} linestyle i-1 + +)~"; + + + const string GNUPLOT_SCATTER_REGRESSION = R"~(# +# +# set arrow 1 from graph 0, first 1 to graph 1, first 30 nohead ls 9 @@ -131,14 +153,31 @@ plot $RunData using 1:3 with impulses linestyle 3, \ )~"; - } + template + inline string + renderCSV (IT& iter) + { + return join (iter, "\n"); + } + }//(End)template and defaults definitions /** */ string dataPlot (CSVRowIter& rowIT) { - UNIMPLEMENTED ("generate gnuplot"); + TextTemplate plot{GNUPLOT_BASIC_PLOT_DEF + +GNUPLOT_SIMPLE_DATA_PLOT}; + + auto config + = MakeRec() + .set ("CommonStyleDef", GNUPLOT_CommonStyleDef) + .set ("AxisGridSetup", GNUPLOT_AxisGridSetup) + .set ("DiagramKind", "points") + .set ("CSVData", renderCSV(rowIT)) + .genNode(); + + return plot.render(config); } }} // namespace lib::gnuplot_gen diff --git a/tests/library/gnuplot-gen-test.cpp b/tests/library/gnuplot-gen-test.cpp index 32749c284..6463390d9 100644 --- a/tests/library/gnuplot-gen-test.cpp +++ b/tests/library/gnuplot-gen-test.cpp @@ -85,7 +85,7 @@ namespace test { }; auto csvIter = explore(data).asIterSource(); string gnuplot = gnuplot_gen::dataPlot (csvIter); - + cout << gnuplot < - + @@ -112011,9 +112011,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + + @@ -112054,7 +112054,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -112158,6 +112158,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + +
@@ -112267,7 +112270,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -112300,7 +112303,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

- Das Desig ist bewußt minimalistisch (und damit handwerklich orientiert): Es ist ein Werkzeug, keine Komponente aus dem Baukasten. + Das Design ist bewußt minimalistisch (und damit handwerklich orientiert): Es ist ein Werkzeug, keine Komponente aus dem Baukasten.

  • @@ -112319,12 +112322,23 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + + + + + +

    + ...in der Hoffnung, daß ich sie dort dann demnächst wiederfinde... +

    + +
    + +
    @@ -114294,17 +114308,15 @@ std::cout << tmpl.render({"what", "World"}) << s - - + + - - - +

    watt soll der Jeitz @@ -114316,7 +114328,9 @@ std::cout << tmpl.render({"what", "World"}) << s - + + + @@ -114335,6 +114349,39 @@ std::cout << tmpl.render({"what", "World"}) << s + + + + + + + +

    + ...wegen möglichen Style-Adjustments, die ggfs. eine spezielle Datenspalte auswerten könnten, um Entscheidungen zu treffen — allesamt Entscheidungen, die man notfalls auch hart-gecodet als Parameter durchgeben könnte +

    + + +
    +
    + + + + +

    + manches Problem kann man auch in Gnuplot lösen... +

    + + +
    + + + + + + + +
    +
    @@ -114352,25 +114399,48 @@ std::cout << tmpl.render({"what", "World"}) << s - + + + + +

    + ...relevant immer wenn die Daten als Linien-Plot (wie eine Funktion) dargestellt werden sollen, denn dann müssen die Zeilen nach Abszissenwert aufsteigend sortiert sein +

    + +
    - + - - - - + + + + - + + + + + + + + + + + + + + + + @@ -114397,10 +114467,20 @@ std::cout << tmpl.render({"what", "World"}) << s - - + + + + + + + + + + + + @@ -123451,6 +123531,41 @@ unsigned int ThreadIdAsInt = *static_cast<unsigned int*>(static_cast<vo + + + + + + +

    + $RunData << _End_of_Data_ +

    +

    +  name1 name2 name3 +

    +

    + 11 22 33 +

    +

    + _End_of_Data_ +

    +

    + +

    +

    + stats $RunData nooutput +

    +

    + print STATS_columns +

    + +
    +
    + + + + +
    @@ -123488,6 +123603,17 @@ unsigned int ThreadIdAsInt = *static_cast<unsigned int*>(static_cast<vo + + + + + + + + + + + @@ -123624,7 +123750,7 @@ unsigned int ThreadIdAsInt = *static_cast<unsigned int*>(static_cast<vo - + @@ -123685,6 +123811,7 @@ unsigned int ThreadIdAsInt = *static_cast<unsigned int*>(static_cast<vo +