From 1c0d0cb262bab4bba9751fb0b1ae337ba250b3a7 Mon Sep 17 00:00:00 2001 From: jkriege2 Date: Sat, 24 Sep 2022 20:18:08 +0200 Subject: [PATCH] updated documentation (better structure & more info) --- Doxyfile | 12 +- doc/dox/examples_and_tutorials.dox | 16 +- doc/dox/jkqtplotter.dox | 12 +- doc/dox/jkqtplotter_01naming.dox | 25 - doc/dox/jkqtplotter_02principles.dox | 48 -- doc/dox/jkqtplotter_04plotelements.dox | 513 ------------------ doc/dox/jkqtplotter_baseplotelements.dox | 22 + doc/dox/jkqtplotter_datastorage.dox | 19 + ...x => jkqtplotter_datastorage_classdoc.dox} | 10 +- doc/dox/jkqtplotter_graphs.dox | 182 +++++++ doc/dox/jkqtplotter_naming.dox | 29 + doc/dox/jkqtplotter_plotelements.dox | 182 +++++++ doc/dox/jkqtplotter_plotelements_classdoc.dox | 346 ++++++++++++ ..._05styling.dox => jkqtplotter_styling.dox} | 7 +- doc/dox/jkqtplotter_stylingclassdoc.dox | 13 + doc/dox/jkqtplotter_usage.dox | 154 ++++++ doc/dox/whatsnew.dox | 52 +- doc/images/plot_elements.greenshot | Bin 0 -> 72592 bytes doc/images/plot_elements.png | Bin 0 -> 71076 bytes examples/simpletest/simpletest.cpp | 2 +- lib/jkqtplotter/jkqtpbaseplotter.h | 40 +- lib/jkqtplotter/jkqtpbaseplotterstyle.h | 6 +- lib/jkqtplotter/jkqtpcoordinateaxes.h | 10 +- lib/jkqtplotter/jkqtpcoordinateaxesstyle.h | 6 +- lib/jkqtplotter/jkqtpdatastorage.h | 16 +- lib/jkqtplotter/jkqtpgraphsbasestyle.h | 8 +- lib/jkqtplotter/jkqtpkeystyle.h | 2 +- lib/jkqtplotter/jkqtplotter.h | 84 +-- lib/jkqtplotter/jkqtplotterstyle.h | 6 +- lib/jkqtplotter/jkqtptools.h | 14 +- 30 files changed, 1042 insertions(+), 794 deletions(-) delete mode 100644 doc/dox/jkqtplotter_01naming.dox delete mode 100644 doc/dox/jkqtplotter_02principles.dox delete mode 100644 doc/dox/jkqtplotter_04plotelements.dox create mode 100644 doc/dox/jkqtplotter_baseplotelements.dox create mode 100644 doc/dox/jkqtplotter_datastorage.dox rename doc/dox/{jkqtplotter_03datastorage.dox => jkqtplotter_datastorage_classdoc.dox} (90%) create mode 100644 doc/dox/jkqtplotter_graphs.dox create mode 100644 doc/dox/jkqtplotter_naming.dox create mode 100644 doc/dox/jkqtplotter_plotelements.dox create mode 100644 doc/dox/jkqtplotter_plotelements_classdoc.dox rename doc/dox/{jkqtplotter_05styling.dox => jkqtplotter_styling.dox} (96%) create mode 100644 doc/dox/jkqtplotter_stylingclassdoc.dox create mode 100644 doc/dox/jkqtplotter_usage.dox create mode 100644 doc/images/plot_elements.greenshot create mode 100644 doc/images/plot_elements.png diff --git a/Doxyfile b/Doxyfile index 38043acaf8..4b29207058 100644 --- a/Doxyfile +++ b/Doxyfile @@ -2330,12 +2330,7 @@ PREDEFINED = DOXYGEN \ # definition found in the source code. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -EXPAND_AS_DEFINED = " -JKQTCOMMON_LIB_EXPORT" \ - JKQTPLOTTER_LIB_EXPORT \ - JKQTCOMMON_STATISTICS_AND_MATH_LIB_EXPORT \ - JKQTFASTPLOTTER_LIB_EXPORT \ - JKQTMATHTEXT_LIB_EXPORT +EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will # remove all references to function-like macros that are alone on a line, have @@ -2637,7 +2632,10 @@ DOT_PATH = DOTFILE_DIRS = doc/dot/ \ ./doc/dot/ \ doc/dot \ - ./doc/dot + ./doc/dot \ + doc/dot \ + dot \ + ../dot # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the \mscfile diff --git a/doc/dox/examples_and_tutorials.dox b/doc/dox/examples_and_tutorials.dox index 099a8fdb88..6507b5dff6 100644 --- a/doc/dox/examples_and_tutorials.dox +++ b/doc/dox/examples_and_tutorials.dox @@ -9,7 +9,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int \section jkqtp_extut_jkqtplotter Examples&Tutorials for JKQTPlotter -\subsection jkqtp_extut_plotstyles Different Plot Data Styles +\subsection jkqtp_extut_plotstyles Examples for Different Plot Data Styles
ScreenshotDescriptionNotes @@ -91,7 +91,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
-\subsection jkqtp_extut_geometric Geometric Forms, Arrows, Annotaions ... +\subsection jkqtp_extut_geometric Examples for Geometric Forms, Arrows, Annotaions ...
Screenshot Description Notes @@ -106,7 +106,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int `JKQTPGeoEllipse`, `JKQTPGeoArc`, `JKQTPGeoChord`, `JKQTPGeoPie`
-\subsection jkqtp_extut_keyaxesstyles Styling the Plot, Keys, Axes, ... +\subsection jkqtp_extut_keyaxesstyles Examples for Styling the Plot, Keys, Axes, ...
Screenshot Description Notes @@ -129,7 +129,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int -\subsection jkqtp_extut_plotimagedata Image data Plots +\subsection jkqtp_extut_plotimagedata Examples for Image data Plots
Screenshot Description Notes @@ -170,7 +170,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int -\subsection jkqtp_extut_guitools GUI Tools +\subsection jkqtp_extut_guitools Examples for GUI Tools
Screenshot Description Notes @@ -183,7 +183,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
-\subsection jkqtp_extut_guitoolslayout Layout & Styling +\subsection jkqtp_extut_guitoolslayout Examples for Layout & Styling
Screenshot Description Notes @@ -199,7 +199,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
-\subsection jkqtp_extut_datamanagement Data Management & Statistics +\subsection jkqtp_extut_datamanagement Examples for Data Management & Statistics
Screenshot Description Notes @@ -241,7 +241,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
-\subsection jkqtp_extut_cmake_build CMake Build System +\subsection jkqtp_extut_cmake_build Examples for CMake Build System
Screenshot Description Notes diff --git a/doc/dox/jkqtplotter.dox b/doc/dox/jkqtplotter.dox index c4b3f80257..39424297ff 100644 --- a/doc/dox/jkqtplotter.dox +++ b/doc/dox/jkqtplotter.dox @@ -10,9 +10,15 @@ A Qt based plotter for 2D scientific graphs. Main Plotting widget is JKQTPlotter This group assembles documentation of general principles and definitions behind the JKQTPlotter library. +\defgroup jkqtplotter_classdoc Type/Class/Function Documentation +\ingroup jkqtplotter + +This group assembles the documentation of the actual classes, types and functions in the JKQTPlotter library. + + \defgroup jkqtpplotterclasses Plotter Class & Plotter Widget -\ingroup jkqtplotter +\ingroup jkqtplotter_classdoc This group contains the actual plotter classes, that implement layout management code, coordinate system management an actual plotter widget ... @@ -24,10 +30,10 @@ There are two main classes: \defgroup jkqtpplottersupprt Support Classes and Functions -\ingroup jkqtplotter +\ingroup jkqtplotter_classdoc \defgroup jkqtpqtwidgetsttools Qt Widgets/Tools to work with JKQTPlotter -\ingroup jkqtplotter +\ingroup jkqtplotter_classdoc This group assembles several Qt widgets and tool classes that are linked to JKQTPlotter/JKQTBasePlotter and allow to build advanced GUIs for these (e.g. model/view access to internal data ...) diff --git a/doc/dox/jkqtplotter_01naming.dox b/doc/dox/jkqtplotter_01naming.dox deleted file mode 100644 index fd167e5642..0000000000 --- a/doc/dox/jkqtplotter_01naming.dox +++ /dev/null @@ -1,25 +0,0 @@ -/*! - - \defgroup jkqtplotter_naming Conventions Naming Conventions in JKQTPlotter - \ingroup jkqtplotter_general - - - This page assembles the naming conventions behind the implementation and documentation of JKQTPlotter: -
    -
  • \b plot is the complete drawn image, including the axes, the graphs, the key and all other visual elements - It is drawn by the invisible JKQTBasePlotter, which is typically controlled by an actual widget like JKQTPlotter -
  • plot element any sub element of the plot, e.g. a single coordinate axis, the key, but also any graph/curve -
  • \b graph is a single curve/image/geometric element in the plot, typically derived from JKQTPGraph (see also - \ref jkqtplotter_graphsgroup_classstructure_basics ) -
  • geometric element is a special graph that does not represent a curve based on data from the JKQTPDatastore, - but a single graphic element, like a rectangle/circle/line/..., some text, a single symbol. These elements are typically - derived from JKQTPGeometricPlotElement -
  • \b annotation is a plot element, which is used to annotate the graphs/plot, e.g. some text. These elements are typically - derived from JKQTPPlotAnnotationElement -
  • \b key is the legend of the plot -
  • coordinate axis is each of the x- or y-axis (there might be addition axes, e.g. when showing a color-scale) -
- - - -*/ \ No newline at end of file diff --git a/doc/dox/jkqtplotter_02principles.dox b/doc/dox/jkqtplotter_02principles.dox deleted file mode 100644 index 7919fa101e..0000000000 --- a/doc/dox/jkqtplotter_02principles.dox +++ /dev/null @@ -1,48 +0,0 @@ -/*! - - \defgroup jkqtplotter_basicprinciples Basic Principles of JKQTPlotter - \ingroup jkqtplotter_general - - This page documents some basic principles behind the design of the JKQTPlotter library. - - \tableofcontents - - \section jkqtplotter_basicprinciples_datastorage Datastorage - Data is stored in an (internal) instance of JKQTPDatastore, which is accessible through JKQTPlotter::getDatastore() or JKQTBasePlotter::getDatastore(). - This datastore can either own its data (which is done here, as we copy the data into the store - e.g. by calling JKQTPDatastore::addCopiedColumn(), or it can merely reference to the data (then - data needs to be available as array of \c double values). - - In addition JKQTPDatastore provides different functions to add or edit the contained data. Amongst others it also provides a C++ StdLib-type iterator - interface to access the data. - - \see JKQTPDatastore, - \ref jkqtpdatastorage , - \ref jkqtp_extut_datamanagement - - \section jkqtplotter_basicprinciples_graphs_and_mixins Graphs & Mix-Ins - - Each graph is represented by a class derived from JKQTPPlotElement (e.g. JKQTPXYLineGraph, - which shows data as a scatter of symbols that may (or may not) be connected by a line). - - There is a complete hirarchy of graph base classes, from which different graphs (or more general plot elements) are derived, - see \ref jkqtplotter_graphsgroup_classstructure_basics . - - - Constructing a graph class does not yet add it to the plotter. To add it, call JKQTBasePlotter::addGraph() / JKQTPlotter::addGraph(). Only - after this step, the graph is displayed. You can modify the apperance of the graph (e.g. colors, name in the key ...) by setting - properties in the graph class instance. - - Most graph peroperties are inserted into the graph class via mix-in classes. - A Mixin allows to inject the same code into different classes, but does not require these classes to be in the same inheritance - tree. The style of mix-in programming used in the JKQTPlotter library is multiple-inheritance. So a graph class is derived from - JKQTPGraph but also has additional parent classes from \ref jkqtplotter_basegraphs_stylemixins like: - - JKQTPGraphLineStyleMixin which provides line-styling - - JKQTPGraphSymbolStyleMixin which provides styling for graph symbols - - JKQTPGraphFillStyleMixin which provides fill styles - - ... - . - - - -*/ \ No newline at end of file diff --git a/doc/dox/jkqtplotter_04plotelements.dox b/doc/dox/jkqtplotter_04plotelements.dox deleted file mode 100644 index 955504fd1b..0000000000 --- a/doc/dox/jkqtplotter_04plotelements.dox +++ /dev/null @@ -1,513 +0,0 @@ -/*! - - -\defgroup jkqtplotter_elements Plot Elements -\ingroup jkqtplotter - -This group assembles all classes that represent different elements of a plot (managed by JKQTBasePlotter/JKQTPlotter). -There are these major subgroups: - - \ref jkqtpbaseplotter_elements contains all non-graph objects, i.e. things like coordinate axes and so on - - \ref jkqtplotter_graphsgroup contains the actual graph classes -. - -\defgroup jkqtpbaseplotter_elements Basic (non-graph) Plot Elements (coordinate axes, ...) -\ingroup jkqtplotter_elements - -This group contains some tool classes that implement basic elements of the plot (coordinate axes, key, ...). -These classes are used by JKQTPlotterBase to output the plot. - - -\defgroup jkqtplotter_graphsgroup Graph Classes -\ingroup jkqtplotter_elements - -This group contains all classes in the JKQTPlotter library that may be used to draw a graph (i.e. a curve) onto a plot. - -\tableofcontents - -\section jkqtplotter_graphsgroup_classstructure Graph Class Structure - -\subsection jkqtplotter_graphsgroup_classstructure_basics Graph Classes - -Each type of graph is represented by another class, which has to be derived from JKQTPPlotElement. This class provides a basic virtual interface -that allows JKQTPlotter to draw the graphs represented by them. This interface consists of these functions: - - JKQTPPlotElement::draw() draws the graph onto a given JKQTPEnhancedPainter (derived from QPainter) - - JKQTPPlotElement::drawKeyMarker() draws the small marker image in the plot legend - - JKQTPPlotElement::getKeyLabelColor() returns a color for the legend entry for the graph - - JKQTPPlotElement::getXMinMax() returns the extent of the graph in x-direction (e.g. for auto-zooming) - - JKQTPPlotElement::getYMinMax() returns the extent of the graph in Y-direction (e.g. for auto-zooming) -. -In addition to these basic functions, there are additional functions that can be used to draw something outside the actual plot rectangle. -These are used to e.g. add color-scales to the side of the graph: - - JKQTPPlotElement::getOutsideSize() returns the amount of space required outside the plot rectangle - - JKQTPPlotElement::drawOutside() draws the elements outside the plot rectangle -. - -Usually if writing a new graph, one would not directly -derive from JKQTPPlotElement, but from a cass in it's hirarchy of children. These children already provide certain facilities for certain types of graphs. - -\dot -digraph -{ - // LATEX_PDF_SIZE - bgcolor="transparent"; - edge [fontname="FreeSans",fontsize="12",labelfontname="FreeSans",labelfontsize="12"]; - node [fontname="FreeSans",fontsize="12"]; - rankdir="LR"; - - { - rank=same; - JKQTPPlotElement [URL="\link JKQTPPlotElement"]; - noteJKQTPPlotElement [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nelements drawn\nonto a plot"]; - JKQTPPlotElement -> noteJKQTPPlotElement [style=dashed,arrowhead=none]; - } - - { - rank=same; - JKQTPGraph [URL="\link JKQTPPlotElement"]; - noteJKQTPGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nactual graphs"]; - JKQTPGraph -> noteJKQTPGraph [style=dashed,arrowhead=none]; - - JKQTPGeometricPlotElement [URL="\link JKQTPGeometricPlotElement"]; - noteJKQTPGeometricPlotElement [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nnon-graph elements,\ne.g. geometric elements"]; - JKQTPGeometricPlotElement -> noteJKQTPGeometricPlotElement [style=dashed,arrowhead=none]; - - JKQTPPlotAnnotationElement [URL="\link JKQTPPlotAnnotationElement"]; - noteJKQTPPlotAnnotationElement [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraph annotation elements,\ne.g. text, symbols, ranges ..."]; - JKQTPPlotAnnotationElement -> noteJKQTPPlotAnnotationElement [style=dashed,arrowhead=none]; - } - - - { - rank=same; - - JKQTPXYGraph [URL="\link JKQTPXYGraph"] - noteJKQTPXYGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x,y) data pairs"]; - JKQTPXYGraph -> noteJKQTPXYGraph [style=dashed,arrowhead=none]; - - JKQTPSingleColumnGraph [URL="\link JKQTPSingleColumnGraph"] - noteJKQTPSingleColumnGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on only\n a single column of data"]; - JKQTPSingleColumnGraph -> noteJKQTPSingleColumnGraph [style=dashed,arrowhead=none]; - - JKQTPImageBase [URL="\link JKQTPImageBase"] - noteJKQTPImageBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \n2D images/matrices"]; - JKQTPImageBase -> noteJKQTPImageBase [style=dashed,arrowhead=none]; - } - - { - rank=same; - - JKQTPXYYGraph [URL="\link JKQTPXYYGraph"] - noteJKQTPXYYGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x, y1, y2) data tripels"]; - JKQTPXYYGraph -> noteJKQTPXYYGraph [style=dashed,arrowhead=none]; - - JKQTPXXYGraph [URL="\link JKQTPXXYGraph"] - noteJKQTPXXYGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x1, x2, y) data tripels"]; - JKQTPXXYGraph -> noteJKQTPXXYGraph [style=dashed,arrowhead=none]; - - JKQTPXYBaselineGraph [URL="\link JKQTPXYBaselineGraph"] - noteJJKQTPXYBaselineGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x,y) data pairs and a baseline"]; - JKQTPXYBaselineGraph -> noteJJKQTPXYBaselineGraph [style=dashed,arrowhead=none]; - - JKQTPEvaluatedFunctionGraphBase [URL="\link JKQTPEvaluatedFunctionGraphBase"] - noteJKQTPEvaluatedFunctionGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \ndynamically evaluated functions"]; - JKQTPEvaluatedFunctionGraphBase -> noteJKQTPEvaluatedFunctionGraphBase [style=dashed,arrowhead=none]; - - JKQTPMathImageBase [URL="\link JKQTPMathImageBase"] - noteJKQTPMathImageBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ndata-based images"]; - JKQTPMathImageBase -> noteJKQTPMathImageBase [style=dashed,arrowhead=none]; - } - - { - rank=same; - - JKQTPBarGraphBase [URL="\link JKQTPBarGraphBase"] - noteJKQTPBarGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nbarcharts"]; - JKQTPBarGraphBase -> noteJKQTPBarGraphBase [style=dashed,arrowhead=none]; - - JKQTPFilledCurveGraphBase [URL="\link JKQTPFilledCurveGraphBase"] - noteJKQTPFilledCurveGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nfilled graphs"]; - JKQTPFilledCurveGraphBase -> noteJKQTPFilledCurveGraphBase [style=dashed,arrowhead=none]; - - JKQTPImpulsesGraphBase [URL="\link JKQTPImpulsesGraphBase"] - noteJKQTPImpulsesGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nimpulse graphs"]; - JKQTPImpulsesGraphBase -> noteJKQTPImpulsesGraphBase [style=dashed,arrowhead=none]; - - JKQTPSpecialLineGraphBase [URL="\link JKQTPSpecialLineGraphBase"] - noteJKQTPSpecialLineGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nspecial line graphs"]; - JKQTPSpecialLineGraphBase -> noteJKQTPSpecialLineGraphBase [style=dashed,arrowhead=none]; - - JKQTPBoxplotGraphBase [URL="\link JKQTPBoxplotGraphBase"] - noteJKQTPBoxplotGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \na set of boxplots"]; - JKQTPBoxplotGraphBase -> noteJKQTPBoxplotGraphBase [style=dashed,arrowhead=none]; - - JKQTPRangeBase [URL="\link JKQTPRangeBase"]; - noteJKQTPRangeBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nrange annotations"]; - JKQTPRangeBase -> noteJKQTPRangeBase [style=dashed,arrowhead=none]; - - JKQTPBoxplotElementBase [URL="\link JKQTPBoxplotElementBase"] - noteJKQTPBoxplotElementBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \na single boxplot"]; - JKQTPBoxplotElementBase -> noteJKQTPBoxplotElementBase [style=dashed,arrowhead=none]; - - JKQTPViolinplotElementBase [URL="\link JKQTPViolinplotElementBase"] - noteJKQTPViolinplotElementBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \na single violin plot"]; - JKQTPViolinplotElementBase -> noteJKQTPViolinplotElementBase [style=dashed,arrowhead=none]; - } - - JKQTPPlotElement -> JKQTPGraph - JKQTPPlotElement -> JKQTPGeometricPlotElement - JKQTPPlotElement -> JKQTPPlotAnnotationElement - JKQTPPlotElement -> JKQTPRangeBase - JKQTPPlotElement -> JKQTPBoxplotElementBase - JKQTPPlotElement -> JKQTPViolinplotElementBase - - JKQTPGraph -> JKQTPXYGraph - JKQTPGraph -> JKQTPSingleColumnGraph - JKQTPGraph -> JKQTPImageBase -> JKQTPMathImageBase - JKQTPGraph -> JKQTPEvaluatedFunctionGraphBase - JKQTPGraph -> JKQTPBoxplotGraphBase - - JKQTPXYGraph -> JKQTPXYYGraph - JKQTPXYGraph -> JKQTPXXYGraph - JKQTPXYGraph -> JKQTPXYBaselineGraph - - JKQTPXYBaselineGraph -> JKQTPBarGraphBase - JKQTPXYBaselineGraph -> JKQTPFilledCurveGraphBase - JKQTPXYBaselineGraph -> JKQTPImpulsesGraphBase - JKQTPXYBaselineGraph -> JKQTPSpecialLineGraphBase - -} - -\enddot - -\subsection jkqtplotter_graphsgroup_classstructure_mixins Mix-In Classes for Graphs - -\see \ref jkqtplotter_basicprinciples_graphs_and_mixins - -In addition there are mix-in classes that are used via multiple inheritance -that add additional features and properties to a graph. A prominent example are the classes for \ref jkqtplotter_basegraphserrors "error indicators". -With these there are usually two variants of one type of graph: One without error indicators and one with error indicators, e.g.: - - JKQTPXYLineGraph shows lines+symbols graphs made up from x/y-value pairs for each data point. - - JKQTPXYLineErrorGraph extends JKQTPXYLineGraph with error indicator drawing/properties provided by JKQTPXYGraphErrors -. -This approach allows to keep interfaces and appearance recognizeable over different graph classes and locates the source code -for a feature like error indicators in a single/in few class(es). - -Another example of such a class is JKQTPColorPaletteStyleAndToolsMixin, which provides functions that allow to use color palettes. It is -mainly used for the \ref jkqtplotter_imagelots "Image/Matrix graphs", but also by e.g. JKQTPXYParametrizedScatterGraph. - -\defgroup jkqtplotter_basegraphs Baseclasses for Graphs -\ingroup jkqtplotter_graphsgroup - -\defgroup jkqtplotter_basegraphserrors Mix-In Classes for Error Indicators -\ingroup jkqtplotter_basegraphs - -\defgroup jkqtplotter_basegraphs_stylemixins Mix-In Classes for Plot Styling -\ingroup jkqtplotter_basegraphs - -\defgroup jkqtplotter_linesymbolgraphs Line/Symbol Graphs -\ingroup jkqtplotter_graphsgroup - -This group assembles graphs that show their data with symbols and optionally with connecting lines in diferent styles: - - - - - - - -
Screenshot - Classes -
\image html beeswarmplot_small.png - JKQTPSingleColumnSymbolsGraph -
\image html JKQTPXYScatterGraph_small.png - JKQTPXYScatterGraph, JKQTPXYScatterErrorGraph -
\image html symbols_and_styles_small.png - JKQTPXYLineGraph, JKQTPXYLineErrorGraph -
\image html paramscatterplot_small.png - JKQTPXYParametrizedScatterGraph, JKQTPXYParametrizedErrorScatterGraph -
\image html stepplots_small.png - JKQTPSpecialLineHorizontalGraph, JKQTPSpecialLineVerticalGraph -
- -\defgroup jkqtplotter_linesymbolgraphs_simple Basic Line/Scatter Graphs -\ingroup jkqtplotter_linesymbolgraphs - - - - - - -
Screenshot - Classes -
\image html beeswarmplot_small.png - JKQTPSingleColumnSymbolsGraph -
\image html symbols_and_styles_small.png - JKQTPXYLineGraph, JKQTPXYLineErrorGraph -
\image html stepplots_small.png - JKQTPSpecialLineHorizontalGraph, JKQTPSpecialLineVerticalGraph -
- - -\defgroup jkqtplotter_linesymbolgraphs_param Parametrized Line/Scatter Graphs -\ingroup jkqtplotter_linesymbolgraphs - - - - -
Screenshot - Classes -
\image html paramscatterplot_small.png - JKQTPXYParametrizedScatterGraph, JKQTPXYParametrizedErrorScatterGraph -
- -\defgroup jkqtplotter_filledgraphs Filled Polygon/Area Graphs -\ingroup jkqtplotter_graphsgroup - - - - - - -
Screenshot - Classes -
\image html filledgraphs_small.png - JKQTPFilledCurveXGraph, JKQTPFilledCurveYGraph -
\image html JKQTPFilledCurveXErrorGraph_small.png - JKQTPFilledCurveXErrorGraph, JKQTPFilledCurveYErrorGraph -
\image html JKQTPfilledVerticalRangeGraph_WithLines_small.png - JKQTPFilledVerticalRangeGraph, JKQTPFilledHorizontalRangeGraph -
- -\defgroup jkqtplotter_functiongraphs Function Graphs -\ingroup jkqtplotter_linesymbolgraphs - - - - - -
Screenshot - Classes -
\image html functionplot_small.png - JKQTPXFunctionLineGraph, JKQTPYFunctionLineGraph -
\image html evalcurve_small.png - JKQTPXYFunctionLineGraph -
- -\defgroup jkqtplotter_parsedFgraphs Parsed Function Graphs -\ingroup jkqtplotter_linesymbolgraphs - - - - -
Screenshot - Classes -
\image html functionplot_small.png - JKQTPXParsedFunctionLineGraph, JKQTPYParsedFunctionLineGraph -
- -\defgroup jkqtplotter_barssticks Barcharts, Impulse-Charts, ... -\ingroup jkqtplotter_graphsgroup - - - - - - - - -
Screenshot - Classes -
\image html barchart_small.png - JKQTPBarVerticalGraph, JKQTPBarHorizontalGraph -
\image html barchart_error_small.png - JKQTPBarVerticalErrorGraph, JKQTPBarHorizontalErrorGraph -
\image html JKQTPbarVerticalGraphStacked_small.png - JKQTPBarVerticalStackableGraph, JKQTPBarHorizontalStackableGraph -
\image html impulsesplot_small.png - JKQTPImpulsesHorizontalGraph, JKQTPImpulsesVerticalGraph -
\image html impulses_errors_small.png - JKQTPImpulsesHorizontalErrorGraph, JKQTPImpulsesVerticalErrorGraph -
- -\defgroup jkqtplotter_statgraphs Statistical Graphs (e.g. Boxplots ...) -\ingroup jkqtplotter_graphsgroup - - - - - -
Screenshot - Classes -
\image html boxplot_small.png - JKQTPBoxplotVerticalGraph, JKQTPBoxplotHorizontalGraph -
\image html JKQTPViolinplotVerticalElement_small.png - JKQTPViolinplotVerticalElement, JKQTPViolinplotHorizontalElement -
- -\see \ref jkqtptools_math_statistics_adaptors for shortcuts to calculate statistical properties of data and then adding a plot with the results. - -\defgroup jkqtplotter_geoplots Geometric Elements (Lines, Rectangles, ...) -\ingroup jkqtplotter_graphsgroup - - - - - - - - - - - - - -
Screenshot - Classes -
\image html symbol_filled_diamond.png - JKQTPGeoSymbol -
\image html geo_text_small.png - JKQTPGeoText -
\image html geo_line_small.png - JKQTPGeoLine, JKQTPGeoInfiniteLine, JKQTPGeoPolyLines -
\image html geo_arrows_small.png - JKQTPGeoArrow -
\image html geo_rect_small.png - JKQTPGeoRectangle -
\image html geo_polygon_small.png - JKQTPGeoPolygon -
\image html geo_ellipse_small.png - JKQTPGeoEllipse -
\image html geo_arc_small.png - JKQTPGeoArc -
\image html geo_pie_small.png - JKQTPGeoPie -
\image html geo_chords_small.png - JKQTPGeoChord -
- -Examples: - - \ref JKQTPlotterGeometricGraphs -. - -\defgroup jkqtplotter_annotations Graph Annotations -\ingroup jkqtplotter_graphsgroup - - - - - - -
Screenshot - Classes -
\image html symbol_filled_diamond.png - JKQTPGeoSymbol -
\image html geo_text_small.png - JKQTPGeoText -
\image html JKQTPHorizontalRange_small.png - JKQTPHorizontalRange, JKQTPVerticalRange -
- -Examples: - - \ref JKQTPlotterGeometricGraphs -. - -\defgroup jkqtplotter_diverse Diverse Other Graphs (Ranges, ...) -\ingroup jkqtplotter_graphsgroup - - - - - - -
Screenshot - Classes -
\image html JKQTPPeakStreamGraphY_small.png - JKQTPPeakStreamGraph -
\image html geo_boxplot_small.png - JKQTPBoxplotVerticalElement, JKQTPBoxplotHorizontalElement -
\image html JKQTPViolinplotVerticalElement_small.png - JKQTPViolinplotVerticalElement, JKQTPViolinplotHorizontalElement -
- -\defgroup jkqtplotter_imagelots Matrix/Image Plotting -\ingroup jkqtplotter_graphsgroup - - - - - - - - - -
Screenshot - Classes -
\image html rgbimageplot_qt_small.png - JKQTPImage -
\image html JKQTPMathImageBaseModifyNone_small.png - JKQTPMathImage, JKQTPColumnMathImage -
\image html rgbimageplots_small.png - JKQTPRGBMathImage, JKQTPColumnRGBMathImage -
\image html overlayimage_small.png - JKQTPOverlayImage -
\image html overlayimageenhanced_small.png - JKQTPOverlayImageEnhanced, JKQTPColumnOverlayImageEnhanced -
\image html JKQTPColumnContourPlot_small.png - JKQTPContourPlot, JKQTPColumnContourPlot -
- -\defgroup jkqtplotter_imagelots_elements Image Graphs -\ingroup jkqtplotter_imagelots - - - - - - - -
Screenshot - Classes -
\image html rgbimageplot_qt_small.png - JKQTPImage -
\image html JKQTPMathImageBaseModifyNone_small.png - JKQTPMathImage, JKQTPColumnMathImage -
\image html rgbimageplot_cimg_small.png - JKQTPRGBMathImage, JKQTPColumnRGBMathImage -
- -\defgroup jkqtplotter_imagelots_overlays Image/Matrix Overlay Graphs -\ingroup jkqtplotter_imagelots - - - - - -
Screenshot - Classes -
\image html overlayimage_small.png - JKQTPOverlayImage -
\image html overlayimageenhanced_small.png - JKQTPOverlayImageEnhanced, JKQTPColumnOverlayImageEnhanced -
- -\defgroup jkqtplotter_imagelots_tools Tool Functions & Classes for Image Drawing -\ingroup jkqtplotter_imagelots - -\defgroup jkqtplotter_imagelots_tools_LUTS Tool Functions to Build Lookup-Tables for Palettes -\ingroup jkqtplotter_imagelots_tools - -\defgroup jkqtplotter_imagelots_contour Contour Graphs (based on Image Data) -\ingroup jkqtplotter_imagelots - - - - -
Screenshot - Classes -
\image html JKQTPColumnContourPlot_small.png - JKQTPContourPlot, JKQTPColumnContourPlot -
- - - -*/ \ No newline at end of file diff --git a/doc/dox/jkqtplotter_baseplotelements.dox b/doc/dox/jkqtplotter_baseplotelements.dox new file mode 100644 index 0000000000..2e930b1636 --- /dev/null +++ b/doc/dox/jkqtplotter_baseplotelements.dox @@ -0,0 +1,22 @@ +/*! + + + \defgroup jkqtplotter_general_basicplotelements Non-Graph Plot Elements + \ingroup jkqtplotter_general + + \defgroup jkqtplotter_general_basicplotelements_coordinateaxes Coordinate Axes + \ingroup jkqtplotter_general_basicplotelements + + \copydetails JKQTPCoordinateAxis + + + + \defgroup jkqtplotter_general_basicplotelements_key Plot Key/Legend + \ingroup jkqtplotter_general_basicplotelements + + + +*/ + + + diff --git a/doc/dox/jkqtplotter_datastorage.dox b/doc/dox/jkqtplotter_datastorage.dox new file mode 100644 index 0000000000..318db99680 --- /dev/null +++ b/doc/dox/jkqtplotter_datastorage.dox @@ -0,0 +1,19 @@ +/*! + \defgroup jkqtpdatastorage Data Management and -storage + \ingroup jkqtplotter_general + + Data is stored in an (internal) instance of JKQTPDatastore, which is accessible through JKQTPlotter::getDatastore() or JKQTBasePlotter::getDatastore(). + This datastore can either own its data (which is done here, as we copy the data into the store + e.g. by calling JKQTPDatastore::addCopiedColumn(), or it can merely reference to the data (then + data needs to be available as array of \c double values). + + In addition JKQTPDatastore provides different functions to add or edit the contained data. Amongst others it also provides a C++ StdLib-type iterator + interface to access the data. + + \see \ref jkqtpdatastorage_classes and especially JKQTPDatastore,
+ \ref jkqtp_extut_datamanagement +*/ + + + + diff --git a/doc/dox/jkqtplotter_03datastorage.dox b/doc/dox/jkqtplotter_datastorage_classdoc.dox similarity index 90% rename from doc/dox/jkqtplotter_03datastorage.dox rename to doc/dox/jkqtplotter_datastorage_classdoc.dox index aa3eb7e8cd..e40a2a04b1 100644 --- a/doc/dox/jkqtplotter_03datastorage.dox +++ b/doc/dox/jkqtplotter_datastorage_classdoc.dox @@ -1,7 +1,8 @@ + /*! -\defgroup jkqtpdatastorage Data Storage Classes/System -\ingroup jkqtplotter +\defgroup jkqtpdatastorage_classes Data Storage Classes +\ingroup jkqtplotter_classdoc The classes in this group implement a data storage system for use with the main plotter class. Basically a table of data is generated as a set of logical columns that may be bound to different @@ -9,10 +10,11 @@ data sources (internal or external memory arrays. Later on it is simply possible using the column number and the not a link to the actual data array, as the link is stored in these classes. -\see \ref JKQTPlotterBasicJKQTPDatastore for a detailed description of how to use this class for data management! +\see \ref jkqtpdatastorage +
\ref JKQTPlotterBasicJKQTPDatastore for a detailed description of how to use this class for data management! \defgroup jkqtpexternalinterfaces Interfaces To Other Libraries -\ingroup jkqtpdatastorage +\ingroup jkqtpdatastorage_classes \defgroup jkqtpinterfaceopencv OpenCV Interfaceing Tools diff --git a/doc/dox/jkqtplotter_graphs.dox b/doc/dox/jkqtplotter_graphs.dox new file mode 100644 index 0000000000..29074776ff --- /dev/null +++ b/doc/dox/jkqtplotter_graphs.dox @@ -0,0 +1,182 @@ +/*! + + + \defgroup jkqtplotter_graphsgroup_classstructure Graphs + \ingroup jkqtplotter_general + + \section jkqtplotter_graphsgroup_classstructure_basics Graph Class Structure + + Each type of graph is represented by another class, which has to be derived from JKQTPPlotElement. This class provides a basic virtual interface + that allows JKQTPlotter to draw the graphs represented by them. This interface consists of these functions: + - JKQTPPlotElement::draw() draws the graph onto a given JKQTPEnhancedPainter (derived from QPainter) + - JKQTPPlotElement::drawKeyMarker() draws the small marker image in the plot legend + - JKQTPPlotElement::getKeyLabelColor() returns a color for the legend entry for the graph + - JKQTPPlotElement::getXMinMax() returns the extent of the graph in x-direction (e.g. for auto-zooming) + - JKQTPPlotElement::getYMinMax() returns the extent of the graph in Y-direction (e.g. for auto-zooming) + . + In addition to these basic functions, there are additional functions that can be used to draw something outside the actual plot rectangle. + These are used to e.g. add color-scales to the side of the graph: + - JKQTPPlotElement::getOutsideSize() returns the amount of space required outside the plot rectangle + - JKQTPPlotElement::drawOutside() draws the elements outside the plot rectangle + . + + Usually if writing a new graph, one would not directly + derive from JKQTPPlotElement, but from a cass in it's hirarchy of children. These children already provide certain facilities for certain types of graphs. + + \dot + digraph + { + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"]; + node [fontname="FreeSans",fontsize="10"]; + rankdir="LR"; + + { + rank=same; + JKQTPPlotElement [URL="\ref JKQTPPlotElement"]; + noteJKQTPPlotElement [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nelements drawn\nonto a plot"]; + JKQTPPlotElement -> noteJKQTPPlotElement [style=dashed,arrowhead=none]; + } + + { + rank=same; + JKQTPGraph [URL="\ref JKQTPPlotElement"]; + noteJKQTPGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nactual graphs"]; + JKQTPGraph -> noteJKQTPGraph [style=dashed,arrowhead=none]; + + JKQTPGeometricPlotElement [URL="\ref JKQTPGeometricPlotElement"]; + noteJKQTPGeometricPlotElement [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nnon-graph elements,\ne.g. geometric elements"]; + JKQTPGeometricPlotElement -> noteJKQTPGeometricPlotElement [style=dashed,arrowhead=none]; + + JKQTPPlotAnnotationElement [URL="\ref JKQTPPlotAnnotationElement"]; + noteJKQTPPlotAnnotationElement [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraph annotation elements,\ne.g. text, symbols, ranges ..."]; + JKQTPPlotAnnotationElement -> noteJKQTPPlotAnnotationElement [style=dashed,arrowhead=none]; + } + + + { + rank=same; + + JKQTPXYGraph [URL="\ref JKQTPXYGraph"] + noteJKQTPXYGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x,y) data pairs"]; + JKQTPXYGraph -> noteJKQTPXYGraph [style=dashed,arrowhead=none]; + + JKQTPSingleColumnGraph [URL="\ref JKQTPSingleColumnGraph"] + noteJKQTPSingleColumnGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on only\n a single column of data"]; + JKQTPSingleColumnGraph -> noteJKQTPSingleColumnGraph [style=dashed,arrowhead=none]; + + JKQTPImageBase [URL="\ref JKQTPImageBase"] + noteJKQTPImageBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \n2D images/matrices"]; + JKQTPImageBase -> noteJKQTPImageBase [style=dashed,arrowhead=none]; + } + + { + rank=same; + + JKQTPXYYGraph [URL="\ref JKQTPXYYGraph"] + noteJKQTPXYYGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x, y1, y2) data tripels"]; + JKQTPXYYGraph -> noteJKQTPXYYGraph [style=dashed,arrowhead=none]; + + JKQTPXXYGraph [URL="\ref JKQTPXXYGraph"] + noteJKQTPXXYGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x1, x2, y) data tripels"]; + JKQTPXXYGraph -> noteJKQTPXXYGraph [style=dashed,arrowhead=none]; + + JKQTPXYBaselineGraph [URL="\ref JKQTPXYBaselineGraph"] + noteJJKQTPXYBaselineGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x,y) data pairs and a baseline"]; + JKQTPXYBaselineGraph -> noteJJKQTPXYBaselineGraph [style=dashed,arrowhead=none]; + + JKQTPEvaluatedFunctionGraphBase [URL="\ref JKQTPEvaluatedFunctionGraphBase"] + noteJKQTPEvaluatedFunctionGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \ndynamically evaluated functions"]; + JKQTPEvaluatedFunctionGraphBase -> noteJKQTPEvaluatedFunctionGraphBase [style=dashed,arrowhead=none]; + + JKQTPMathImageBase [URL="\ref JKQTPMathImageBase"] + noteJKQTPMathImageBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ndata-based images"]; + JKQTPMathImageBase -> noteJKQTPMathImageBase [style=dashed,arrowhead=none]; + } + + { + rank=same; + + JKQTPBarGraphBase [URL="\ref JKQTPBarGraphBase"] + noteJKQTPBarGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nbarcharts"]; + JKQTPBarGraphBase -> noteJKQTPBarGraphBase [style=dashed,arrowhead=none]; + + JKQTPFilledCurveGraphBase [URL="\ref JKQTPFilledCurveGraphBase"] + noteJKQTPFilledCurveGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nfilled graphs"]; + JKQTPFilledCurveGraphBase -> noteJKQTPFilledCurveGraphBase [style=dashed,arrowhead=none]; + + JKQTPImpulsesGraphBase [URL="\ref JKQTPImpulsesGraphBase"] + noteJKQTPImpulsesGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nimpulse graphs"]; + JKQTPImpulsesGraphBase -> noteJKQTPImpulsesGraphBase [style=dashed,arrowhead=none]; + + JKQTPSpecialLineGraphBase [URL="\ref JKQTPSpecialLineGraphBase"] + noteJKQTPSpecialLineGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nspecial line graphs"]; + JKQTPSpecialLineGraphBase -> noteJKQTPSpecialLineGraphBase [style=dashed,arrowhead=none]; + + JKQTPBoxplotGraphBase [URL="\ref JKQTPBoxplotGraphBase"] + noteJKQTPBoxplotGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \na set of boxplots"]; + JKQTPBoxplotGraphBase -> noteJKQTPBoxplotGraphBase [style=dashed,arrowhead=none]; + + JKQTPRangeBase [URL="\ref JKQTPRangeBase"]; + noteJKQTPRangeBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nrange annotations"]; + JKQTPRangeBase -> noteJKQTPRangeBase [style=dashed,arrowhead=none]; + + JKQTPBoxplotElementBase [URL="\ref JKQTPBoxplotElementBase"] + noteJKQTPBoxplotElementBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \na single boxplot"]; + JKQTPBoxplotElementBase -> noteJKQTPBoxplotElementBase [style=dashed,arrowhead=none]; + + JKQTPViolinplotElementBase [URL="\ref JKQTPViolinplotElementBase"] + noteJKQTPViolinplotElementBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \na single violin plot"]; + JKQTPViolinplotElementBase -> noteJKQTPViolinplotElementBase [style=dashed,arrowhead=none]; + } + + JKQTPPlotElement -> JKQTPGraph + JKQTPPlotElement -> JKQTPGeometricPlotElement + JKQTPPlotElement -> JKQTPPlotAnnotationElement + JKQTPPlotElement -> JKQTPRangeBase + JKQTPPlotElement -> JKQTPBoxplotElementBase + JKQTPPlotElement -> JKQTPViolinplotElementBase + + JKQTPGraph -> JKQTPXYGraph + JKQTPGraph -> JKQTPSingleColumnGraph + JKQTPGraph -> JKQTPImageBase -> JKQTPMathImageBase + JKQTPGraph -> JKQTPEvaluatedFunctionGraphBase + JKQTPGraph -> JKQTPBoxplotGraphBase + + JKQTPXYGraph -> JKQTPXYYGraph + JKQTPXYGraph -> JKQTPXXYGraph + JKQTPXYGraph -> JKQTPXYBaselineGraph + + JKQTPXYBaselineGraph -> JKQTPBarGraphBase + JKQTPXYBaselineGraph -> JKQTPFilledCurveGraphBase + JKQTPXYBaselineGraph -> JKQTPImpulsesGraphBase + JKQTPXYBaselineGraph -> JKQTPSpecialLineGraphBase + + } + \enddot + + + \section jkqtplotter_graphsgroup_classstructure_mixins Mix-In Classes for Graphs + + \see \ref jkqtplotter_mixins + + In addition there are mix-in classes that are used via multiple inheritance + that add additional features and properties to a graph. A prominent example are the classes for \ref jkqtplotter_basegraphserrors "error indicators". + With these there are usually two variants of one type of graph: One without error indicators and one with error indicators, e.g.: + - JKQTPXYLineGraph shows lines+symbols graphs made up from x/y-value pairs for each data point. + - JKQTPXYLineErrorGraph extends JKQTPXYLineGraph with error indicator drawing/properties provided by JKQTPXYGraphErrors + . + This approach allows to keep interfaces and appearance recognizeable over different graph classes and locates the source code + for a feature like error indicators in a single/in few class(es). + + Another example of such a class is JKQTPColorPaletteStyleAndToolsMixin, which provides functions that allow to use color palettes. It is + mainly used for the \ref jkqtplotter_imagelots "Image/Matrix graphs", but also by e.g. JKQTPXYParametrizedScatterGraph. + + + + +*/ + + + diff --git a/doc/dox/jkqtplotter_naming.dox b/doc/dox/jkqtplotter_naming.dox new file mode 100644 index 0000000000..8ee69ff702 --- /dev/null +++ b/doc/dox/jkqtplotter_naming.dox @@ -0,0 +1,29 @@ +/*! + + \defgroup jkqtplotter_naming Conventions: Naming and Plot Construction + \ingroup jkqtplotter_general + + + This page assembles the naming conventions behind the implementation and documentation of JKQTPlotter (cf. the image below): +
    +
  • \b plot is the complete drawn image, including the axes, the graphs, the key and all other visual elements + It is drawn by the invisible JKQTBasePlotter, which is typically controlled by an actual widget like JKQTPlotter +
  • plot element any sub element of the plot, e.g. a single coordinate axis, the key, but also any graph/curve +
  • \b graph is a single curve/image/geometric element in the plot, typically derived from JKQTPGraph (see also + \ref jkqtplotter_graphsgroup_classstructure_basics ) +
  • geometric element is a special graph that does not represent a curve based on data from the JKQTPDatastore, + but a single geometric element, like a rectangle/circle/line/... These elements are typically + derived from JKQTPGeometricPlotElement +
  • \b annotation is a plot element, which is used to annotate the graphs/plot, e.g. some text. These elements are typically + derived from JKQTPPlotAnnotationElement +
  • \b key is the legend of the plot, showing a list of the graphs, each represented by a entry marker (showing the graphs color/symbol/...) and a entry title. +
  • coordinate axis is each of the x- or y-axis (there might be addition axes, e.g. when showing a color-scale). Each coordinate axis is composed from several elements: the axis line itself, an axis label, axis ticks and corresponding tick labels (major and a second set of minor ticks in between are available) +
  • zero axis: a pair of axes through the origin \c x=0 and \c y=0 of the coordinate system +
  • \b grid a grid of horizontal/vertical lines, drawn behind the graph and providing visual guidance for the viewer of the graph. The grid is actually a part of the coordinate axes, as the lines are positioned at the same position as the axis ticks +
  • minor grid in addition to the grid, corresponding to the major axis ticks, you can add additional lines that correspond to the minor axis ticks +
  • color bar some graphs use a color-scale (e.g. images or parametrized scatter graphs). The color bar displays the used color palette of that graph. It is typically positioned besides or above the plot. +
+ + \image html plot_elements.png + +*/ \ No newline at end of file diff --git a/doc/dox/jkqtplotter_plotelements.dox b/doc/dox/jkqtplotter_plotelements.dox new file mode 100644 index 0000000000..a54886e220 --- /dev/null +++ b/doc/dox/jkqtplotter_plotelements.dox @@ -0,0 +1,182 @@ +/*! + + + \defgroup jkqtplotter_graphsgroup_classstructure Graphs + \ingroup jkqtplotter_general + + \section jkqtplotter_graphsgroup_classstructure_basics Graph Class Structure + + Each type of graph is represented by another class, which has to be derived from JKQTPPlotElement. This class provides a basic virtual interface + that allows JKQTPlotter to draw the graphs represented by them. This interface consists of these functions: + - JKQTPPlotElement::draw() draws the graph onto a given JKQTPEnhancedPainter (derived from QPainter) + - JKQTPPlotElement::drawKeyMarker() draws the small marker image in the plot legend + - JKQTPPlotElement::getKeyLabelColor() returns a color for the legend entry for the graph + - JKQTPPlotElement::getXMinMax() returns the extent of the graph in x-direction (e.g. for auto-zooming) + - JKQTPPlotElement::getYMinMax() returns the extent of the graph in Y-direction (e.g. for auto-zooming) + . + In addition to these basic functions, there are additional functions that can be used to draw something outside the actual plot rectangle. + These are used to e.g. add color-scales to the side of the graph: + - JKQTPPlotElement::getOutsideSize() returns the amount of space required outside the plot rectangle + - JKQTPPlotElement::drawOutside() draws the elements outside the plot rectangle + . + + Usually if writing a new graph, one would not directly + derive from JKQTPPlotElement, but from a cass in it's hirarchy of children. These children already provide certain facilities for certain types of graphs. + + \dot + digraph + { + // LATEX_PDF_SIZE + bgcolor="transparent"; + edge [fontname="FreeSans",fontsize="10",labelfontname="FreeSans",labelfontsize="10"]; + node [fontname="FreeSans",fontsize="10"]; + rankdir="LR"; + + { + rank=same; + JKQTPPlotElement [URL="\ref JKQTPPlotElement"]; + noteJKQTPPlotElement [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nelements drawn\nonto a plot"]; + JKQTPPlotElement -> noteJKQTPPlotElement [style=dashed,arrowhead=none]; + } + + { + rank=same; + JKQTPGraph [URL="\ref JKQTPPlotElement"]; + noteJKQTPGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nactual graphs"]; + JKQTPGraph -> noteJKQTPGraph [style=dashed,arrowhead=none]; + + JKQTPGeometricPlotElement [URL="\ref JKQTPGeometricPlotElement"]; + noteJKQTPGeometricPlotElement [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nnon-graph elements,\ne.g. geometric elements"]; + JKQTPGeometricPlotElement -> noteJKQTPGeometricPlotElement [style=dashed,arrowhead=none]; + + JKQTPPlotAnnotationElement [URL="\ref JKQTPPlotAnnotationElement"]; + noteJKQTPPlotAnnotationElement [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraph annotation elements,\ne.g. text, symbols, ranges ..."]; + JKQTPPlotAnnotationElement -> noteJKQTPPlotAnnotationElement [style=dashed,arrowhead=none]; + } + + + { + rank=same; + + JKQTPXYGraph [URL="\ref JKQTPXYGraph"] + noteJKQTPXYGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x,y) data pairs"]; + JKQTPXYGraph -> noteJKQTPXYGraph [style=dashed,arrowhead=none]; + + JKQTPSingleColumnGraph [URL="\ref JKQTPSingleColumnGraph"] + noteJKQTPSingleColumnGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on only\n a single column of data"]; + JKQTPSingleColumnGraph -> noteJKQTPSingleColumnGraph [style=dashed,arrowhead=none]; + + JKQTPImageBase [URL="\ref JKQTPImageBase"] + noteJKQTPImageBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \n2D images/matrices"]; + JKQTPImageBase -> noteJKQTPImageBase [style=dashed,arrowhead=none]; + } + + { + rank=same; + + JKQTPXYYGraph [URL="\ref JKQTPXYYGraph"] + noteJKQTPXYYGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x, y1, y2) data tripels"]; + JKQTPXYYGraph -> noteJKQTPXYYGraph [style=dashed,arrowhead=none]; + + JKQTPXXYGraph [URL="\ref JKQTPXXYGraph"] + noteJKQTPXXYGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x1, x2, y) data tripels"]; + JKQTPXXYGraph -> noteJKQTPXXYGraph [style=dashed,arrowhead=none]; + + JKQTPXYBaselineGraph [URL="\ref JKQTPXYBaselineGraph"] + noteJJKQTPXYBaselineGraph [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs based on\n (x,y) data pairs and a baseline"]; + JKQTPXYBaselineGraph -> noteJJKQTPXYBaselineGraph [style=dashed,arrowhead=none]; + + JKQTPEvaluatedFunctionGraphBase [URL="\ref JKQTPEvaluatedFunctionGraphBase"] + noteJKQTPEvaluatedFunctionGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \ndynamically evaluated functions"]; + JKQTPEvaluatedFunctionGraphBase -> noteJKQTPEvaluatedFunctionGraphBase [style=dashed,arrowhead=none]; + + JKQTPMathImageBase [URL="\ref JKQTPMathImageBase"] + noteJKQTPMathImageBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ndata-based images"]; + JKQTPMathImageBase -> noteJKQTPMathImageBase [style=dashed,arrowhead=none]; + } + + { + rank=same; + + JKQTPBarGraphBase [URL="\ref JKQTPBarGraphBase"] + noteJKQTPBarGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nbarcharts"]; + JKQTPBarGraphBase -> noteJKQTPBarGraphBase [style=dashed,arrowhead=none]; + + JKQTPFilledCurveGraphBase [URL="\ref JKQTPFilledCurveGraphBase"] + noteJKQTPFilledCurveGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nfilled graphs"]; + JKQTPFilledCurveGraphBase -> noteJKQTPFilledCurveGraphBase [style=dashed,arrowhead=none]; + + JKQTPImpulsesGraphBase [URL="\ref JKQTPImpulsesGraphBase"] + noteJKQTPImpulsesGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nimpulse graphs"]; + JKQTPImpulsesGraphBase -> noteJKQTPImpulsesGraphBase [style=dashed,arrowhead=none]; + + JKQTPSpecialLineGraphBase [URL="\ref JKQTPSpecialLineGraphBase"] + noteJKQTPSpecialLineGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nspecial line graphs"]; + JKQTPSpecialLineGraphBase -> noteJKQTPSpecialLineGraphBase [style=dashed,arrowhead=none]; + + JKQTPBoxplotGraphBase [URL="\ref JKQTPBoxplotGraphBase"] + noteJKQTPBoxplotGraphBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \na set of boxplots"]; + JKQTPBoxplotGraphBase -> noteJKQTPBoxplotGraphBase [style=dashed,arrowhead=none]; + + JKQTPRangeBase [URL="\ref JKQTPRangeBase"]; + noteJKQTPRangeBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\nrange annotations"]; + JKQTPRangeBase -> noteJKQTPRangeBase [style=dashed,arrowhead=none]; + + JKQTPBoxplotElementBase [URL="\ref JKQTPBoxplotElementBase"] + noteJKQTPBoxplotElementBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \na single boxplot"]; + JKQTPBoxplotElementBase -> noteJKQTPBoxplotElementBase [style=dashed,arrowhead=none]; + + JKQTPViolinplotElementBase [URL="\ref JKQTPViolinplotElementBase"] + noteJKQTPViolinplotElementBase [shape="note", color="lightyellow",style=filled,fontsize=8,label="base class for all\ngraphs that represent \na single violin plot"]; + JKQTPViolinplotElementBase -> noteJKQTPViolinplotElementBase [style=dashed,arrowhead=none]; + } + + JKQTPPlotElement -> JKQTPGraph + JKQTPPlotElement -> JKQTPGeometricPlotElement + JKQTPPlotElement -> JKQTPPlotAnnotationElement + JKQTPPlotElement -> JKQTPRangeBase + JKQTPPlotElement -> JKQTPBoxplotElementBase + JKQTPPlotElement -> JKQTPViolinplotElementBase + + JKQTPGraph -> JKQTPXYGraph + JKQTPGraph -> JKQTPSingleColumnGraph + JKQTPGraph -> JKQTPImageBase -> JKQTPMathImageBase + JKQTPGraph -> JKQTPEvaluatedFunctionGraphBase + JKQTPGraph -> JKQTPBoxplotGraphBase + + JKQTPXYGraph -> JKQTPXYYGraph + JKQTPXYGraph -> JKQTPXXYGraph + JKQTPXYGraph -> JKQTPXYBaselineGraph + + JKQTPXYBaselineGraph -> JKQTPBarGraphBase + JKQTPXYBaselineGraph -> JKQTPFilledCurveGraphBase + JKQTPXYBaselineGraph -> JKQTPImpulsesGraphBase + JKQTPXYBaselineGraph -> JKQTPSpecialLineGraphBase + + } + + \enddot + + \section jkqtplotter_graphsgroup_classstructure_mixins Mix-In Classes for Graphs + + \see \ref jkqtplotter_mixins + + In addition there are mix-in classes that are used via multiple inheritance + that add additional features and properties to a graph. A prominent example are the classes for \ref jkqtplotter_basegraphserrors "error indicators". + With these there are usually two variants of one type of graph: One without error indicators and one with error indicators, e.g.: + - JKQTPXYLineGraph shows lines+symbols graphs made up from x/y-value pairs for each data point. + - JKQTPXYLineErrorGraph extends JKQTPXYLineGraph with error indicator drawing/properties provided by JKQTPXYGraphErrors + . + This approach allows to keep interfaces and appearance recognizeable over different graph classes and locates the source code + for a feature like error indicators in a single/in few class(es). + + Another example of such a class is JKQTPColorPaletteStyleAndToolsMixin, which provides functions that allow to use color palettes. It is + mainly used for the \ref jkqtplotter_imagelots "Image/Matrix graphs", but also by e.g. JKQTPXYParametrizedScatterGraph. + + + + +*/ + + + diff --git a/doc/dox/jkqtplotter_plotelements_classdoc.dox b/doc/dox/jkqtplotter_plotelements_classdoc.dox new file mode 100644 index 0000000000..dab790cfb9 --- /dev/null +++ b/doc/dox/jkqtplotter_plotelements_classdoc.dox @@ -0,0 +1,346 @@ + + +/*! + + +\defgroup jkqtplotter_elements Plot Element Classes +\ingroup jkqtplotter_classdoc + +This group assembles all classes that represent different elements of a plot (managed by JKQTBasePlotter/JKQTPlotter). +There are these major subgroups: + - \ref jkqtpbaseplotter_elements contains all non-graph objects, i.e. things like coordinate axes and so on + - \ref jkqtplotter_concretegraphs contains the actual graph classes +. + +\defgroup jkqtpbaseplotter_elements Non-Graph Plot Elements +\ingroup jkqtplotter_elements + +This group contains some tool classes that implement basic elements of the plot (coordinate axes, key, ...). +These classes are used by JKQTPlotterBase to output the plot. + + + +\defgroup jkqtplotter_basegraphs Baseclasses for Graphs +\ingroup jkqtplotter_elements + +\defgroup jkqtplotter_mixins Mix-in classes for Graphs +\ingroup jkqtplotter_elements + +\defgroup jkqtplotter_basegraphserrors Mix-In Classes for Error Indicators +\ingroup jkqtplotter_mixins + +\defgroup jkqtplotter_basegraphs_stylemixins Mix-In Classes for Plot Styling +\ingroup jkqtplotter_mixins + + +\defgroup jkqtplotter_concretegraphs Concrete Graph Classes +\ingroup jkqtplotter_elements + + +\defgroup jkqtplotter_linesymbolgraphs Line/Symbol Graphs +\ingroup jkqtplotter_concretegraphs + +This group assembles graphs that show their data with symbols and optionally with connecting lines in diferent styles: + + + + + + + +
Screenshot + Classes +
\image html beeswarmplot_small.png + JKQTPSingleColumnSymbolsGraph +
\image html JKQTPXYScatterGraph_small.png + JKQTPXYScatterGraph, JKQTPXYScatterErrorGraph +
\image html symbols_and_styles_small.png + JKQTPXYLineGraph, JKQTPXYLineErrorGraph +
\image html paramscatterplot_small.png + JKQTPXYParametrizedScatterGraph, JKQTPXYParametrizedErrorScatterGraph +
\image html stepplots_small.png + JKQTPSpecialLineHorizontalGraph, JKQTPSpecialLineVerticalGraph +
+ +\defgroup jkqtplotter_linesymbolgraphs_simple Basic Line/Scatter Graphs +\ingroup jkqtplotter_linesymbolgraphs + + + + + + +
Screenshot + Classes +
\image html beeswarmplot_small.png + JKQTPSingleColumnSymbolsGraph +
\image html symbols_and_styles_small.png + JKQTPXYLineGraph, JKQTPXYLineErrorGraph +
\image html stepplots_small.png + JKQTPSpecialLineHorizontalGraph, JKQTPSpecialLineVerticalGraph +
+ + +\defgroup jkqtplotter_linesymbolgraphs_param Parametrized Line/Scatter Graphs +\ingroup jkqtplotter_linesymbolgraphs + + + + +
Screenshot + Classes +
\image html paramscatterplot_small.png + JKQTPXYParametrizedScatterGraph, JKQTPXYParametrizedErrorScatterGraph +
+ +\defgroup jkqtplotter_filledgraphs Filled Polygon/Area Graphs +\ingroup jkqtplotter_concretegraphs + + + + + + +
Screenshot + Classes +
\image html filledgraphs_small.png + JKQTPFilledCurveXGraph, JKQTPFilledCurveYGraph +
\image html JKQTPFilledCurveXErrorGraph_small.png + JKQTPFilledCurveXErrorGraph, JKQTPFilledCurveYErrorGraph +
\image html JKQTPfilledVerticalRangeGraph_WithLines_small.png + JKQTPFilledVerticalRangeGraph, JKQTPFilledHorizontalRangeGraph +
+ +\defgroup jkqtplotter_functiongraphs Function Graphs +\ingroup jkqtplotter_linesymbolgraphs + + + + + +
Screenshot + Classes +
\image html functionplot_small.png + JKQTPXFunctionLineGraph, JKQTPYFunctionLineGraph +
\image html evalcurve_small.png + JKQTPXYFunctionLineGraph +
+ +\defgroup jkqtplotter_parsedFgraphs Parsed Function Graphs +\ingroup jkqtplotter_linesymbolgraphs + + + + +
Screenshot + Classes +
\image html functionplot_small.png + JKQTPXParsedFunctionLineGraph, JKQTPYParsedFunctionLineGraph +
+ +\defgroup jkqtplotter_barssticks Barcharts, Impulse-Charts, ... +\ingroup jkqtplotter_concretegraphs + + + + + + + + +
Screenshot + Classes +
\image html barchart_small.png + JKQTPBarVerticalGraph, JKQTPBarHorizontalGraph +
\image html barchart_error_small.png + JKQTPBarVerticalErrorGraph, JKQTPBarHorizontalErrorGraph +
\image html JKQTPbarVerticalGraphStacked_small.png + JKQTPBarVerticalStackableGraph, JKQTPBarHorizontalStackableGraph +
\image html impulsesplot_small.png + JKQTPImpulsesHorizontalGraph, JKQTPImpulsesVerticalGraph +
\image html impulses_errors_small.png + JKQTPImpulsesHorizontalErrorGraph, JKQTPImpulsesVerticalErrorGraph +
+ +\defgroup jkqtplotter_statgraphs Statistical Graphs (e.g. Boxplots ...) +\ingroup jkqtplotter_concretegraphs + + + + + +
Screenshot + Classes +
\image html boxplot_small.png + JKQTPBoxplotVerticalGraph, JKQTPBoxplotHorizontalGraph +
\image html JKQTPViolinplotVerticalElement_small.png + JKQTPViolinplotVerticalElement, JKQTPViolinplotHorizontalElement +
+ +\see \ref jkqtptools_math_statistics_adaptors for shortcuts to calculate statistical properties of data and then adding a plot with the results. + +\defgroup jkqtplotter_geoplots Geometric Elements (Lines, Rectangles, ...) +\ingroup jkqtplotter_concretegraphs + + + + + + + + + + + + + +
Screenshot + Classes +
\image html symbol_filled_diamond.png + JKQTPGeoSymbol +
\image html geo_text_small.png + JKQTPGeoText +
\image html geo_line_small.png + JKQTPGeoLine, JKQTPGeoInfiniteLine, JKQTPGeoPolyLines +
\image html geo_arrows_small.png + JKQTPGeoArrow +
\image html geo_rect_small.png + JKQTPGeoRectangle +
\image html geo_polygon_small.png + JKQTPGeoPolygon +
\image html geo_ellipse_small.png + JKQTPGeoEllipse +
\image html geo_arc_small.png + JKQTPGeoArc +
\image html geo_pie_small.png + JKQTPGeoPie +
\image html geo_chords_small.png + JKQTPGeoChord +
+ +Examples: + - \ref JKQTPlotterGeometricGraphs +. + +\defgroup jkqtplotter_annotations Graph Annotations +\ingroup jkqtplotter_concretegraphs + + + + + + +
Screenshot + Classes +
\image html symbol_filled_diamond.png + JKQTPGeoSymbol +
\image html geo_text_small.png + JKQTPGeoText +
\image html JKQTPHorizontalRange_small.png + JKQTPHorizontalRange, JKQTPVerticalRange +
+ +Examples: + - \ref JKQTPlotterGeometricGraphs +. + +\defgroup jkqtplotter_diverse Diverse Other Graphs (Ranges, ...) +\ingroup jkqtplotter_concretegraphs + + + + + + +
Screenshot + Classes +
\image html JKQTPPeakStreamGraphY_small.png + JKQTPPeakStreamGraph +
\image html geo_boxplot_small.png + JKQTPBoxplotVerticalElement, JKQTPBoxplotHorizontalElement +
\image html JKQTPViolinplotVerticalElement_small.png + JKQTPViolinplotVerticalElement, JKQTPViolinplotHorizontalElement +
+ +\defgroup jkqtplotter_imagelots Matrix/Image Plotting +\ingroup jkqtplotter_concretegraphs + + + + + + + + + +
Screenshot + Classes +
\image html rgbimageplot_qt_small.png + JKQTPImage +
\image html JKQTPMathImageBaseModifyNone_small.png + JKQTPMathImage, JKQTPColumnMathImage +
\image html rgbimageplots_small.png + JKQTPRGBMathImage, JKQTPColumnRGBMathImage +
\image html overlayimage_small.png + JKQTPOverlayImage +
\image html overlayimageenhanced_small.png + JKQTPOverlayImageEnhanced, JKQTPColumnOverlayImageEnhanced +
\image html JKQTPColumnContourPlot_small.png + JKQTPContourPlot, JKQTPColumnContourPlot +
+ +\defgroup jkqtplotter_imagelots_elements Image Graphs +\ingroup jkqtplotter_imagelots + + + + + + + +
Screenshot + Classes +
\image html rgbimageplot_qt_small.png + JKQTPImage +
\image html JKQTPMathImageBaseModifyNone_small.png + JKQTPMathImage, JKQTPColumnMathImage +
\image html rgbimageplot_cimg_small.png + JKQTPRGBMathImage, JKQTPColumnRGBMathImage +
+ +\defgroup jkqtplotter_imagelots_overlays Image/Matrix Overlay Graphs +\ingroup jkqtplotter_imagelots + + + + + +
Screenshot + Classes +
\image html overlayimage_small.png + JKQTPOverlayImage +
\image html overlayimageenhanced_small.png + JKQTPOverlayImageEnhanced, JKQTPColumnOverlayImageEnhanced +
+ +\defgroup jkqtplotter_imagelots_tools Tool Functions & Classes for Image Drawing +\ingroup jkqtplotter_imagelots + +\defgroup jkqtplotter_imagelots_tools_LUTS Tool Functions to Build Lookup-Tables for Palettes +\ingroup jkqtplotter_imagelots_tools + +\defgroup jkqtplotter_imagelots_contour Contour Graphs (based on Image Data) +\ingroup jkqtplotter_imagelots + + + + +
Screenshot + Classes +
\image html JKQTPColumnContourPlot_small.png + JKQTPContourPlot, JKQTPColumnContourPlot +
+ + + +*/ \ No newline at end of file diff --git a/doc/dox/jkqtplotter_05styling.dox b/doc/dox/jkqtplotter_styling.dox similarity index 96% rename from doc/dox/jkqtplotter_05styling.dox rename to doc/dox/jkqtplotter_styling.dox index 1aa79240b0..77815fd73c 100644 --- a/doc/dox/jkqtplotter_05styling.dox +++ b/doc/dox/jkqtplotter_styling.dox @@ -2,7 +2,7 @@ \defgroup jkqtpplotter_styling Styling System -\ingroup jkqtplotter +\ingroup jkqtplotter_general \image html stylesbanner.png @@ -70,8 +70,9 @@ Here is a table with all available ready-made styles:
\image html simple_axesoffset_plotbox.ini.png
-\see For a detailed example, see \ref JKQTPlotterStyling +\see Classes are documented in \ref jkqtpplotter_styling_classes . +
See \ref JKQTPlotterStyling for a detailed example. -*/ \ No newline at end of file +*/ diff --git a/doc/dox/jkqtplotter_stylingclassdoc.dox b/doc/dox/jkqtplotter_stylingclassdoc.dox new file mode 100644 index 0000000000..466cac0f76 --- /dev/null +++ b/doc/dox/jkqtplotter_stylingclassdoc.dox @@ -0,0 +1,13 @@ + +/*! + + +\defgroup jkqtpplotter_styling_classes Styling System Classes +\ingroup jkqtplotter_classdoc + +This group assembles all classes that for the styling system of JKQTPlotter. + +\see \ref jkqtpplotter_styling + + +*/ \ No newline at end of file diff --git a/doc/dox/jkqtplotter_usage.dox b/doc/dox/jkqtplotter_usage.dox new file mode 100644 index 0000000000..2a72265999 --- /dev/null +++ b/doc/dox/jkqtplotter_usage.dox @@ -0,0 +1,154 @@ +/*! + + + \defgroup jkqtplotter_general_usage Usage of JKQTPlotter + \ingroup jkqtplotter_general + + \defgroup jkqtplotter_general_usage_jkqtbaseplotter Usage of JKQTBasePlotter Non-Visible Class + \ingroup jkqtplotter_general_usage + + It is also possible to use it in a standalone fashion to generate plots without generating a window. + Note that the baseplotter class still requires the \c widgets+gui modules of Qt, because it contains code to e.g. + display pint or export preview dialogs! + + Here is an example of how to do this (it is taken from the command-line tool \ref JKQTPlotterDocImageRenderCmdLineTool): + + First we generate the JKQTBasePlotter object and add some data to the internal JKQTPDatastore + \code + JKQTBasePlotter plot(true); + JKQTPDatastore* ds=plot.getDatastore(); + size_t cx=ds->addCopiedColumn(QVector{-1.5,-0.5,0.5,1.5,2.5},"x"); + size_t cy=ds->addCopiedColumn(QVector{-0.75,-0.3,-0.05,0.2,0.65},"y"); + \endcode + + Now we set the range of x/y plot coordinates ... + \code + plot.setXY(-0.8,2.2,-0.5,0.7); + \endcode + and the size of the widget, i.e. the size of the plot in the windowing system. + \code + plot.setWidgetSize(150,50); + \endcode + Now we can add graphs to the plotter, e.g. + \code + JKQTPXYLineGraph* g=new JKQTPXYLineGraph(&plot); + g->setXColumn(cx); + g->setYColumn(cy); + plot.addGraph(g); + \endcode + Finally we store an image of the plot as PNG-file: + \code + plot.saveAsPixelImage("output.png", false, "png"); + \endcode + Alternatively you can obtain a QImage of the plot using JKQTBasePlotter::grabPixelImage() or copy the + image to the clipboard using JKQTBasePlotter::copyPixelImage(). Also storages as PDF and SVG is available via + JKQTBasePlotter::saveAsPDF() and JKQTBasePlotter::saveAsSVG(). + + With simlar code you can also integrate JKQTBasePlotter into your own widgets. + + + + + + + + \defgroup jkqtplotter_general_usage_jkqtplotter Usage of JKQTPlotter Widget + \ingroup jkqtplotter_general_usage + + JKQTPlotter is a plotter widget which wraps around a JKQTBasePlotter instanced that does the actual drawing. + A basic usage of JKQTPlotter looks like this: + + \code{.cpp} + // create a new JKQTPlotter instance + JKQTPlotter* plot = new JKQTPlotter(parentWidget); + + // fill two vectors with dtaa for a graph: + QVector X, Y; + fillDataVectors(X, Y); + + // make data available to the internal datastore of the plotter: + size_t columnX=plot->getDatastore()->addCopiedColumn(X, "x"); + size_t columnY=plot->getDatastore()->addCopiedColumn(Y, "y"); + + // create a graph/curve, which displays the data + JKQTPXYLineGraph* graph1=new JKQTPXYLineGraph(plot); + graph1->setXColumn(columnX); + graph1->setYColumn(columnY); + graph1->setTitle(QObject::tr("graph title")); + plot->addGraph(graph1); + + // autoscale the plot + plot->zoomToFit(); + // alternatively set the axis dimension by hand: + plot->setXY(-10,10,-10,10); + \endcode + + The result should look something like this: + + \image html simpletest.png + + Starting from this basic example, you can observe several important principles: +
    +
  1. Data is stored in an (internal) instance of JKQTPDatastore, which is accessible through + JKQTPlotter::getDatastore(). + This datastore can either own its data (which is done here, as we copy the data into the store + by calling JKQTPDatastore::addCopiedColumn(), or it can merely reference to the data (then + data needs to be available as array of \c double values). +
  2. Naming conventions (excerpt from \ref jkqtplotter_naming ): +
      +
    • \b plot is the complete drawn image, including the axes, the graphs, the key and all other visual elements +
    • plot element any sub element of the plot, e.g. a single coordinate axis, the key, but also any graph/curve +
    • \b graph is a single curve/image/geometric element in the plot +
    • geometric element is a special graph that does not represent a curve based on data from the JKQTPDatastore, + but a single graphic element, like a rectangle/circle/line/..., some text, a single symbol +
    • \b key is the legend of the plot +
    • coordinate axis is each of the x- or y-axis (there might be addition axes, e.g. when showing a color-scale) +
    +
  3. Each graph is represented by a class derived from JKQTPPlotElement (in the example we instanciated a JKQTPXYLineGraph, + which shows data as a scatter of symbols that may (or may not) be connected by a line). + Creating the graph class does not yet add it to the plotter. To add it, call JKQTPlotter::addGraph(). Only + after this sep, the graph is displayed. You can modify the apperance of the graph (e.g. colors, + name in the key ...) by setting properties in the graph class instance. +
  4. You can auto-zoom the axis ranges of the plot by calling JKQTPlotter::zoomToFit(), or set them + exlicitly by calling JKQTPlotter::setXY(). The user can later zoom in/out by the mouse (and other means). + You can limit this zoom range by setting an absolute axis range, calling e.g. JKQTPlotter::setAbsoluteXY(). + The the user cannot zoom farther out than the given range(s). +
  5. If you want to style the plot itself, you need to set properties of the underlying JKQTBasePloter instance, which + is accessible through JKQTPlotter::getPlotter(). If you want to style the coordinate axes, you can acces their + representing objects by caling JKQTPlotter::getXAxis() or JKQTPlotter::getYAxis(). +
+ + \see \ref JKQTPlotterSimpleTest and \see JKQTPlotterQtCreator + + + + + + + \defgroup jkqtplotter_general_usage_qtcreator How to use JKQTPlotter in the Qt Form Designer + \ingroup jkqtplotter_general_usage + + + As JKQTPlotter is a standard Qt widget, you can also use it in Qt UI-files designed with the Qt From Designer (e.g. from within QTCreator). + For this to work you have to use the Promote QWidget"-feature of the form designer. The steps you need to take are detailed below: +
    +
  1. add a new UI-file to your project and open it in the Form Editor. Then right-click the form and select `Promote Widgets ...`: + + \image html uidesigner_step1.png +
  2. +
  3. In the dialog that opens, you have to define `JKQTPlotter` as a promotion to `QWidget` as shown below. Finally store the settings by clicking `Add` and closing the dialog with `Close`. + + \image html uidesigner_step2.png +
  4. +
  5. Now you can add a `QWidget`from the side-bar to the form and then promote it to `JKQTPlotter`, by selecting and right-clicking the `QWidget` and then selecting `Promote To | JKQTPlotter`: + + \image html uidesigner_step3.png +
  6. +
+ + \see \ref JKQTPlotterQtCreator
Also see \ref JKQTPlotterStyling for another example of using the Qt UI Designer with JKQTPlotter + +*/ + + + diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox index 644e8f7d83..87f08831b2 100644 --- a/doc/dox/whatsnew.dox +++ b/doc/dox/whatsnew.dox @@ -134,11 +134,11 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include: \subsection page_whatsnew_TRUNK_DOWNLOAD trunk: Download -This release is available from: - - Source code branch: https://github.com/jkriege2/JKQtPlotter - - Source Code download (ZIP): https://github.com/jkriege2/JKQtPlotter/archive/master.zip - - Git-Link: https://github.com/jkriege2/JKQtPlotter.git -. +This release is available from @@ -152,7 +152,7 @@ Changes, compared to \ref page_whatsnew_V2019_11 "v2019.11" include:
  • fixed issue #38: Buffer overflow, thanks to user:zertyz
  • fixed issue #43: jkqtp_format() had undefined behaviour, thanks to user:Makis42
  • fixed issue #41: Build error when JKQtPlotter_BUILD_INCLUDE_XITS_FONTS set to OFF , thanks to user:smistad
  • -
  • fixed issue #37: CMake installs things into $PREFIX/doc/*.txt , thanks to user:certik
  • +
  • fixed issue #37: CMake installs things into $PREFIX/doc/ *.txt , thanks to user:certik
  • fixed issue #45: Build error on mac jkqtfastplotter.cpp:342:28: Variable has incomplete type 'QPainterPath', thanks to user:abdedixit
  • merged PR #47: Some minor build fixes, thanks to user:patstew
  • fixed issue #48: Cannot \#include QPrintPreviewWidget, thanks to user:schlenger
  • @@ -194,10 +194,10 @@ Changes, compared to \ref page_whatsnew_V2019_11 "v2019.11" include: \subsection page_whatsnew_V4_0_0_DOWNLOAD V4.0.0: Download -This release is available from: - - Source code branch: https://github.com/jkriege2/JKQtPlotter/tree/v4.0.0 - - Latest Release/Tag: https://github.com/jkriege2/JKQtPlotter/releases/tag/v4.0.0 (2021-April-xx) -. +This release is available from @@ -264,10 +264,10 @@ Changes, compared to \ref page_whatsnew_V2018_08 "v2018.08" include: \subsection page_whatsnew_V2019_11_DOWNLOAD v2019.11: Download -This release is available from: - - Source code branch: https://github.com/jkriege2/JKQtPlotter/tree/v2019.11 - - Latest Release/Tag: https://github.com/jkriege2/JKQtPlotter/releases/tag/v2019.11.1 (2019-Dec-05) -. +This release is available from @@ -276,17 +276,17 @@ This release is available from: \section page_whatsnew_V2018_08 v2018.08: Minor Modifications (Final QuickFit3-compatible Version) \subsection page_whatsnew_V2018_08_OVERVIEW v2018.08: Overview -This is the final version of JKQTPlotter, which is still compatible with the QuickFit 3.0 code base. It contains minor changes as compared to \ref page_whatsnew_V2015_10 "v2015.10": - - new: added Qt data model to switch graphs on/off - - update: some improvements to test programs -. +This is the final version of JKQTPlotter, which is still compatible with the QuickFit 3.0 code base. It contains minor changes as compared to \ref page_whatsnew_V2015_10 "v2015.10"
      +
    • new: added Qt data model to switch graphs on/off +
    • update: some improvements to test programs +
    \subsection page_whatsnew_V2018_08_DOWNLOAD v2018.08: Download -This release is available from: - - Source code branch: https://github.com/jkriege2/JKQtPlotter/tree/v2018.08 - - Latest Release/Tag: https://github.com/jkriege2/JKQtPlotter/releases/tag/v2018.08 (2018-Aug-19) -. +This release is available from @@ -302,10 +302,10 @@ This is the initial release of the library. It was developed initially as part o \subsection page_whatsnew_V2015_10_DOWNLOAD v2015.10: Download -This release is available from: - - Source code branch: https://github.com/jkriege2/JKQtPlotter/tree/v2015.10 - - Latest Release/Tag: https://github.com/jkriege2/JKQtPlotter/releases/tag/v2015.10 (2015-Oct-20) -. +This release is available from */ diff --git a/doc/images/plot_elements.greenshot b/doc/images/plot_elements.greenshot new file mode 100644 index 0000000000000000000000000000000000000000..65129f7c505d7bc77286b7f55930636ca825cd8a GIT binary patch literal 72592 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 BFfIT9 literal 0 HcmV?d00001 diff --git a/examples/simpletest/simpletest.cpp b/examples/simpletest/simpletest.cpp index 3aea733d42..7821b7b38f 100644 --- a/examples/simpletest/simpletest.cpp +++ b/examples/simpletest/simpletest.cpp @@ -6,7 +6,7 @@ #include #include "jkqtplotter/jkqtplotter.h" -#include "jkqtplotter/graphs/jkqtpscatter.h" +#include "jkqtplotter/graphs/jkqtplines.h" #include "jkqtpexampleapplication.h" diff --git a/lib/jkqtplotter/jkqtpbaseplotter.h b/lib/jkqtplotter/jkqtpbaseplotter.h index e6331a21c5..b4499c5946 100644 --- a/lib/jkqtplotter/jkqtpbaseplotter.h +++ b/lib/jkqtplotter/jkqtpbaseplotter.h @@ -334,46 +334,10 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPPaintDeviceAdapter { * Most commonly this invisible plotter class is used as basis for the widget JKQTPlotter. * \see JKQTPlotter * - * \subsection jkqtplotter_usage_baseplotter_standalonw JKQTBasePlotter Standalone Usage + * \subsection jkqtplotter_usage_baseplotter_standalone JKQTBasePlotter Standalone Usage * - * But it is also possible to use it in a standalone fashion to generate plots without generating a window. - * Note that the baseplotter class still requires the \c widgets+gui modules of Qt, because it contains code to e.g. - * display pint or export preview dialogs! + * \copydetails jkqtplotter_general_usage_jkqtplotter * - * Here is an example of how to do this (it is taken from the command-line tool \ref JKQTPlotterDocImageRenderCmdLineTool): - * - * First we generate the JKQTBasePlotter object and add some data to the internal JKQTPDatastore - * \code - * JKQTBasePlotter plot(true); - * JKQTPDatastore* ds=plot.getDatastore(); - * size_t cx=ds->addCopiedColumn(QVector{-1.5,-0.5,0.5,1.5,2.5},"x"); - * size_t cy=ds->addCopiedColumn(QVector{-0.75,-0.3,-0.05,0.2,0.65},"y"); - * \endcode - * - * Now we set the range of x/y plot coordinates ... - * \code - * plot.setXY(-0.8,2.2,-0.5,0.7); - * \endcode - * and the size of the widget, i.e. the size of the plot in the windowing system. - * \code - * plot.setWidgetSize(150,50); - * \endcode - * Now we can add graphs to the plotter, e.g. - * \code - * JKQTPXYLineGraph* g=new JKQTPXYLineGraph(&plot); - * g->setXColumn(cx); - * g->setYColumn(cy); - * plot.addGraph(g); - * \endcode - * Finally we store an image of the plot as PNG-file: - * \code - * plot.saveAsPixelImage("output.png", false, "png"); - * \endcode - * Alternatively you can obtain a QImage of the plot using grabPixelImage() or copy the - * image to the clipboard using copyPixelImage(). ALso storages as PDF and SVG is available via - * saveAsPDF() and saveAsSVG(). - * - * With simlar code you can also integrate JKQTBasePlotter into your own widgets. */ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject { Q_OBJECT diff --git a/lib/jkqtplotter/jkqtpbaseplotterstyle.h b/lib/jkqtplotter/jkqtpbaseplotterstyle.h index 52a0a2d62a..58707bf5ea 100644 --- a/lib/jkqtplotter/jkqtpbaseplotterstyle.h +++ b/lib/jkqtplotter/jkqtpbaseplotterstyle.h @@ -40,7 +40,7 @@ /** \brief Support Class for JKQTBasePlotter, which summarizes all properties that define the visual styling of a JKQTBasePlotter - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTBasePlotter, \ref jkqtpplotter_styling */ @@ -171,14 +171,14 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotterStyle { }; /** \brief returns the system-wide default JKQTPlotterStyle - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTPGetSystemDefaultStyle(), JKQTPSetSystemDefaultStyle(), JKQTPSetSystemDefaultBaseStyle(), \ref jkqtpplotter_styling */ JKQTPLOTTER_LIB_EXPORT JKQTBasePlotterStyle& JKQTPGetSystemDefaultBaseStyle(); /** \brief replaces the system-wide default JKQTPlotterStyle with the given \a newStyle - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTPGetSystemDefaultStyle(), JKQTPSetSystemDefaultStyle(), JKQTPGetSystemDefaultBaseStyle(), \ref jkqtpplotter_styling */ diff --git a/lib/jkqtplotter/jkqtpcoordinateaxes.h b/lib/jkqtplotter/jkqtpcoordinateaxes.h index f3151f3890..7c0ca5c340 100644 --- a/lib/jkqtplotter/jkqtpcoordinateaxes.h +++ b/lib/jkqtplotter/jkqtpcoordinateaxes.h @@ -39,7 +39,7 @@ class JKQTBasePlotter; /*! \brief this virtual class is the base for any type of coordinate axis, to be drawn by JKQTBasePlotter. \ingroup jkqtpbaseplotter_elements - This class implements all the functionality needed for a coordinate axis: + Class derived from JKQTPCoordinateAxis implements all the functionality needed for a coordinate axis: - transform world to screen coordinates and vice versa - draw the axis (implemented by child classes!) with these elements: axis lines, ticks, tick labels, axis label, x/y=0 axis - measure the axes in screen coordinates @@ -263,7 +263,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPCoordinateAxis: public QObject { inline double getUserTickSpacing() const { return this->userTickSpacing; } /** \copydoc userLogTickSpacing */ inline double getUserLogTickSpacing() const { return this->userLogTickSpacing; } - /** \copydoc JKQTPCoordinateAxisStyle::labelType */ + /** \copydoc JKQTPCoordinateAxisStyle::tickLabelType */ inline JKQTPCALabelType getTickLabelType() const { return this->axisStyle.tickLabelType; } /** \copydoc axisLabel */ inline QString getAxisLabel() const { return this->axisLabel; } @@ -472,7 +472,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPCoordinateAxis: public QObject { /** \copydoc userLogTickSpacing */ void setUserLogTickSpacing (double __value); - /** \copydoc JKQTPCoordinateAxisStyle::labelType */ + /** \copydoc JKQTPCoordinateAxisStyle::tickLabelType */ void setTickLabelType (JKQTPCALabelType __value); /** \copydoc JKQTPCoordinateAxisStyle::tickMode */ @@ -867,8 +867,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPVerticalAxis: public JKQTPCoordinateAxis { * \param labelOffset offset of the label from ( \a xx , \a yy ) in pt, this is typically equal to \c tickOuterLength+tickLabelDistance * \param label text to display * \param fontSize the fontSize of the label (in pt) - * \param ascentMax maximum ascent of all tick labels - * \param descentMax maximum descent of all tick labels * \param isMinor indicates whether the axis tick is a minor tick */ void drawTickLabel1(JKQTPEnhancedPainter& painter, double xx, double yy, double labelOffset, const QString &label, double fontSize, bool isMinor=false) ; @@ -880,8 +878,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPVerticalAxis: public JKQTPCoordinateAxis { * \param labelOffset offset of the label from ( \a xx , \a yy ) in pt, this is typically equal to \c tickOuterLength+tickLabelDistance * \param label text to display * \param fontSize the fontSize of the label (in pt) - * \param ascentMax maximum ascent of all tick labels - * \param descentMax maximum descent of all tick labels * \param isMinor indicates whether the axis tick is a minor tick */ void drawTickLabel2(JKQTPEnhancedPainter& painter, double xx, double yy, double labelOffset, const QString &label, double fontSize, bool isMinor=false) ; diff --git a/lib/jkqtplotter/jkqtpcoordinateaxesstyle.h b/lib/jkqtplotter/jkqtpcoordinateaxesstyle.h index 480f5f226d..7bea43d2e6 100644 --- a/lib/jkqtplotter/jkqtpcoordinateaxesstyle.h +++ b/lib/jkqtplotter/jkqtpcoordinateaxesstyle.h @@ -31,7 +31,7 @@ class JKQTBasePlotterStyle; // forward /** \brief Support Class for JKQTPCoordinateAxis, and summarizes all properties that define the visual styling of a grid (minor or major), associated with a JKQTPCoordinateAxis - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTPCoordinateAxis, \ref jkqtpplotter_styling * @@ -71,7 +71,7 @@ public: /** \brief Support Class for JKQTPCoordinateAxis, which summarizes all properties that define the visual styling of a JKQTPCoordinateAxis - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTPCoordinateAxis, \ref jkqtpplotter_styling * @@ -215,7 +215,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPCoordinateAxisStyle { /** \brief Support Class for JKQTPCoordinateAxis, which summarizes all properties that define the visual styling of a JKQTPCoordinateAxis * used for colorbars outside the plot - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * The major difference between this dervied version and the base JKQTPCoordinateAxisStyle are differently initialized members. * \see JKQTPCoordinateAxis, \ref jkqtpplotter_styling diff --git a/lib/jkqtplotter/jkqtpdatastorage.h b/lib/jkqtplotter/jkqtpdatastorage.h index 725abb7888..79a5a29ef5 100644 --- a/lib/jkqtplotter/jkqtpdatastorage.h +++ b/lib/jkqtplotter/jkqtpdatastorage.h @@ -50,7 +50,7 @@ class JKQTPColumnBackInserter; // forward declaration /** \brief the types of data in one JKQTdatastoreItem - * \ingroup jkqtpdatastorage + * \ingroup jkqtpdatastorage_classes * * \c JKQTPSingleColumn: * \verbatim @@ -86,7 +86,7 @@ enum class JKQTPDatastoreItemFormat { }; /** \brief This class manages data columns (with entries of type \c double ), used by JKQTPlotter/JKQTBasePlotter to represent data for plots - * \ingroup jkqtpdatastorage + * \ingroup jkqtpdatastorage_classes * * \see \ref JKQTPlotterBasicJKQTPDatastore for a detailed description of how to use this class for data management! * @@ -1434,7 +1434,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPDatastore{ /** \brief internally stores information about one data column. See JKQTPDatastore for more information. - * \ingroup jkqtpdatastorage + * \ingroup jkqtpdatastorage_classes * \internal * * \see JKQTPDatastore @@ -1643,7 +1643,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPColumn { #pragma pack(push,1) /** \brief iterator over the data in the column of a JKQTPDatastore - * \ingroup jkqtpdatastorage + * \ingroup jkqtpdatastorage_classes * * \see JKQTPColumn, JKQTPDatastore::begin(), JKQTPDatastore::end(), JKQTPDatastore, JKQTPConstColumnIterator */ @@ -1908,7 +1908,7 @@ class JKQTPColumnIterator { /** \brief iterator, which allows to insert into a column of a JKQTPDatastore - * \ingroup jkqtpdatastorage + * \ingroup jkqtpdatastorage_classes * * \see JKQTPDatastore::backInserter(), JKQTPDatastore, http://www.cplusplus.com/reference/iterator/insert_iterator/ */ @@ -1954,7 +1954,7 @@ class JKQTPColumnBackInserter { }; /** \brief iterator over the data in the column of a JKQTPDatastore - * \ingroup jkqtpdatastorage + * \ingroup jkqtpdatastorage_classes * * \see JKQTPColumn, JKQTPDatastore::begin(), JKQTPDatastore::end(), JKQTPDatastore, JKQTPColumnIterator */ @@ -2234,7 +2234,7 @@ class JKQTPColumnConstIterator { /** \brief this represents one chunk of memory which can represent one or more columns of data for JKQTBasePlotter. * See JKQTPDatastore for more information. - * \ingroup jkqtpdatastorage + * \ingroup jkqtpdatastorage_classes * * Each chunk of memory is pointed at by a simple double* pointer \c data. the memory layout of the memory layout of * the RAM segment pointed at by \c data is determined by the parameter \c dataformat: @@ -2472,7 +2472,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPDatastoreItem { /** \brief QAbstractTableModel descendent that allows to view data in a JKQTPDatastore - * \ingroup jkqtpdatastorage + * \ingroup jkqtpdatastorage_classes * * \see JKQTPDatastore */ diff --git a/lib/jkqtplotter/jkqtpgraphsbasestyle.h b/lib/jkqtplotter/jkqtpgraphsbasestyle.h index 2644306186..4b10af894d 100644 --- a/lib/jkqtplotter/jkqtpgraphsbasestyle.h +++ b/lib/jkqtplotter/jkqtpgraphsbasestyle.h @@ -41,7 +41,7 @@ class JKQTBasePlotterStyle; // forward /** \brief Support Class for JKQTBasePlotter, which summarizes all properties that define the visual styling of graphs - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTBasePlotter, \ref jkqtpplotter_styling */ @@ -112,7 +112,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTGraphsSpecificStyleProperties { /** \brief Support Class for JKQTBasePlotter, which summarizes all properties that define the visual styling of geometric elements - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTBasePlotter, \ref jkqtpplotter_styling */ @@ -162,7 +162,7 @@ public: /** \brief Support Class for JKQTBasePlotter, which summarizes all properties that define the visual styling of annotation elements - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTBasePlotter, \ref jkqtpplotter_styling */ @@ -210,7 +210,7 @@ public: /** \brief Support Class for JKQTBasePlotter, which summarizes all properties that define the visual styling of a JKQTBasePlotter - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTBasePlotter, \ref jkqtpplotter_styling */ diff --git a/lib/jkqtplotter/jkqtpkeystyle.h b/lib/jkqtplotter/jkqtpkeystyle.h index bb98b6a928..7cc0927b02 100644 --- a/lib/jkqtplotter/jkqtpkeystyle.h +++ b/lib/jkqtplotter/jkqtpkeystyle.h @@ -32,7 +32,7 @@ class JKQTBasePlotterStyle; // forward /** \brief Support Class for JKQTBasePlotter, which summarizes all properties that define the visual styling of the key in a JKQTBasePlotter - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTBasePlotter, JKQTBasePlotterStyle, \ref jkqtpplotter_styling */ diff --git a/lib/jkqtplotter/jkqtplotter.h b/lib/jkqtplotter/jkqtplotter.h index 5827397956..4eb496041a 100644 --- a/lib/jkqtplotter/jkqtplotter.h +++ b/lib/jkqtplotter/jkqtplotter.h @@ -73,70 +73,8 @@ JKQTPLOTTER_LIB_EXPORT void initJKQTPlotterResources(); * * \section JKQTPLOTTER_BASICUSAGE Basic Usage of JKQTPlotter * - * JKQTPlotter is a plotter widget which wraps around a JKQTBasePlotter instanced that does the actual drawing. - * A basic usage of JKQTPlotter looks like this: + * \copydetails jkqtplotter_general_usage_jkqtbaseplotter * - * \code{.cpp} - * // create a new JKQTPlotter instance - * JKQTPlotter* plot = new JKQTPlotter(parentWidget); - * - * // fill two vectors with dtaa for a graph: - * QVector X, Y; - * fillDataVectors(X, Y); - * - * // make data available to the internal datastore of the plotter: - * size_t columnX=plot->getDatastore()->addCopiedColumn(X, "x"); - * size_t columnY=plot->getDatastore()->addCopiedColumn(Y, "y"); - * - * // create a graph/curve, which displays the data - * JKQTPXYLineGraph* graph1=new JKQTPXYLineGraph(plot); - * graph1->setXColumn(columnX); - * graph1->setYColumn(columnY); - * graph1->setTitle(QObject::tr("graph title")); - * plot->addGraph(graph1); - * - * // autoscale the plot - * plot->zoomToFit(); - * // alternatively set the axis dimension by hand: - * plot->setXY(-10,10,-10,10); - * \endcode - * - * The result should look something like this: - * - * \image html simpletest.png - * - * Starting from this basic example, you can observe several important principles: - *
      - *
    1. Data is stored in an (internal) instance of JKQTPDatastore, which is accessible through - * JKQTPlotter::getDatastore(). - * This datastore can either own its data (which is done here, as we copy the data into the store - * by calling JKQTPDatastore::addCopiedColumn(), or it can merely reference to the data (then - * data needs to be available as array of \c double values). - *
    2. Naming conventions (excerpt from \ref jkqtplotter_naming ): - *
        - *
      • \b plot is the complete drawn image, including the axes, the graphs, the key and all other visual elements - *
      • plot element any sub element of the plot, e.g. a single coordinate axis, the key, but also any graph/curve - *
      • \b graph is a single curve/image/geometric element in the plot - *
      • geometric element is a special graph that does not represent a curve based on data from the JKQTPDatastore, - * but a single graphic element, like a rectangle/circle/line/..., some text, a single symbol - *
      • \b key is the legend of the plot - *
      • coordinate axis is each of the x- or y-axis (there might be addition axes, e.g. when showing a color-scale) - *
      - *
    3. Each graph is represented by a class derived from JKQTPPlotElement (in the example we instanciated a JKQTPXYLineGraph, - * which shows data as a scatter of symbols that may (or may not) be connected by a line). - * Creating the graph class does not yet add it to the plotter. To add it, call JKQTPlotter::addGraph(). Only - * after this sep, the graph is displayed. You can modify the apperance of the graph (e.g. colors, - * name in the key ...) by setting properties in the graph class instance. - *
    4. You can auto-zoom the axis ranges of the plot by calling JKQTPlotter::zoomToFit(), or set them - * exlicitly by calling JKQTPlotter::setXY(). The user can later zoom in/out by the mouse (and other means). - * You can limit this zoom range by setting an absolute axis range, calling e.g. JKQTPlotter::setAbsoluteXY(). - * The the user cannot zoom farther out than the given range(s). - *
    5. If you want to style the plot itself, you need to set properties of the underlying JKQTBasePloter instance, which - * is accessible through JKQTPlotter::getPlotter(). If you want to style the coordinate axes, you can acces their - * representing objects by caling JKQTPlotter::getXAxis() or JKQTPlotter::getYAxis(). - *
    - * - * \see \ref JKQTPlotterSimpleTest and \see JKQTPlotterQtCreator * * \section JKQTPLOTTER_SYNCMULTIPLOT Synchronizing Several Plots * @@ -420,25 +358,7 @@ JKQTPLOTTER_LIB_EXPORT void initJKQTPlotterResources(); * * \section JKQTPLOTTER_USEQTCREATOR How to use JKQTPlotter in the Qt Form Designer * - * As JKQTPlotter is a standard Qt widget, you can also use it in Qt UI-files designed with the Qt From Designer (e.g. from within QTCreator). - * For this to work you have to use the Promote QWidget"-feature of the form designer. The steps you need to take are detailed below: - *
      - *
    1. add a new UI-file to your project and open it in the Form Editor. Then right-click the form and select `Promote Widgets ...`: - * - * \image html uidesigner_step1.png - *
    2. - *
    3. In the dialog that opens, you have to define `JKQTPlotter` as a promotion to `QWidget` as shown below. Finally store the settings by clicking `Add` and closing the dialog with `Close`. - * - * \image html uidesigner_step2.png - *
    4. - *
    5. Now you can add a `QWidget`from the side-bar to the form and then promote it to `JKQTPlotter`, by selecting and right-clicking the `QWidget` and then selecting `Promote To | JKQTPlotter`: - * - * \image html uidesigner_step3.png - *
    6. - *
    - * - * \see \ref JKQTPlotterQtCreator
    Also see \ref JKQTPlotterStyling for another example of using the Qt UI Designer with JKQTPlotter - * + * \copydetails jkqtplotter_general_usage_qtcreator */ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget { Q_OBJECT diff --git a/lib/jkqtplotter/jkqtplotterstyle.h b/lib/jkqtplotter/jkqtplotterstyle.h index bcca14ba13..b685831c50 100644 --- a/lib/jkqtplotter/jkqtplotterstyle.h +++ b/lib/jkqtplotter/jkqtplotterstyle.h @@ -33,7 +33,7 @@ /** \brief Support Class for JKQTPlotter, which summarizes all properties that define the visual styling of a JKQTPlotter - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTPlotter, \ref jkqtpplotter_styling */ @@ -158,14 +158,14 @@ public: /** \brief returns the system-wide default JKQTPlotterStyle - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTPSetSystemDefaultStyle(), JKQTPGetSystemDefaultBaseStyle(), JKQTPSetSystemDefaultBaseStyle(), \ref jkqtpplotter_styling */ JKQTPLOTTER_LIB_EXPORT JKQTPlotterStyle& JKQTPGetSystemDefaultStyle(); /** \brief replaces the system-wide default JKQTPlotterStyle with the given \a newStyle - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTPGetSystemDefaultStyle(), JKQTPGetSystemDefaultBaseStyle(), JKQTPSetSystemDefaultBaseStyle(), \ref jkqtpplotter_styling */ diff --git a/lib/jkqtplotter/jkqtptools.h b/lib/jkqtplotter/jkqtptools.h index 8ae288abb3..afe10d3def 100644 --- a/lib/jkqtplotter/jkqtptools.h +++ b/lib/jkqtplotter/jkqtptools.h @@ -250,7 +250,7 @@ typedef QHash JKQTPMouseMoveAction typedef JKQTPMouseMoveActionsHashMap::const_iterator JKQTPMouseMoveActionsHashMapIterator; /** \brief Specifies how a fill-color is derived from a given color - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes */ struct JKQTPLOTTER_LIB_EXPORT JKQTPColorDerivationMode { @@ -342,7 +342,7 @@ public: }; /** \brief use a JKQTPColorDerivationMode to derive a color from \a col as specified - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \param mode the mode of how to modify the given color \a basecolor * \param basecolor the color in which to base the derivation @@ -352,7 +352,7 @@ public: JKQTPLOTTER_LIB_EXPORT QColor JKQTPGetDerivedColor(JKQTPColorDerivationMode mode, const QColor& basecolor); /** \brief construct a QColor, based on the given \a color, but with alpha set to the specified value \a alphaF - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * \see QColorWithAlpha() */ inline QColor QColorWithAlphaF(const QColor& color, qreal alphaF) { @@ -362,7 +362,7 @@ inline QColor QColorWithAlphaF(const QColor& color, qreal alphaF) { } /** \brief construct a QColor, based on the given \a color, but with alpha set to the specified value \a alpha - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * \see QColorWithAlphaF() */ inline QColor QColorWithAlpha(const QColor& color, int alpha) { @@ -372,13 +372,13 @@ inline QColor QColorWithAlpha(const QColor& color, int alpha) { } /** \brief convert a JKQTPColorDerivationMode to a QString - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see String2JKQTPColorDerivationMode(), JKQTPColorDerivationMode */ JKQTPLOTTER_LIB_EXPORT QString JKQTPColorDerivationMode2String(JKQTPColorDerivationMode mode); /** \brief convert a QString (created by JKQTPColorDerivationMode2String() ) to JKQTPColorDerivationMode - * \ingroup jkqtpplotter_styling + * \ingroup jkqtpplotter_styling_classes * * \see JKQTPColorDerivationMode2String(), JKQTPColorDerivationMode */ @@ -452,7 +452,7 @@ enum JKQTPCALabelType { JKQTPCALTfrac, /*!< \brief show numbers as fraction, the number is first rounded to the given precision and then a fraction is calculated and displayed like \f$ \frac{1}{2} \f$ \image html axisstyle/JKQTPCALTfrac.png */ JKQTPCALTslashfrac, /*!< \brief show numbers as fraction, the number is first rounded to the given precision and then a fraction is calculated and displayed like \c 1/2 \image html axisstyle/JKQTPCALTslashfrac.png */ JKQTPCALTsfrac, /*!< \brief show numbers as fraction, the number is first rounded to the given precision and then a fraction is calculated and displayed using \c \\sfrac{1}{2} \image html axisstyle/JKQTPCALTsfrac.png */ - JKQTPCALTintfrac, /*!< \brief show numbers as integral+fraction, the number is first rounded to the given precision and then a fraction is calculated and displayed like \$ -3\frac{1}{2} \f$ \image html axisstyle/JKQTPCALTintfrac.png */ + JKQTPCALTintfrac, /*!< \brief show numbers as integral+fraction, the number is first rounded to the given precision and then a fraction is calculated and displayed like \f$ -3\frac{1}{2} \f$ \image html axisstyle/JKQTPCALTintfrac.png */ JKQTPCALTintslashfrac, /*!< \brief show numbers as integral+fraction, the number is first rounded to the given precision and then a fraction is calculated and displayed like \c 1/2 \image html axisstyle/JKQTPCALTintslashfrac.png */ JKQTPCALTintsfrac, /*!< \brief show numbers as integral+fraction, the number is first rounded to the given precision and then a fraction is calculated and displayed using \c \\sfrac{1}{2} \image html axisstyle/JKQTPCALTintsfrac.png */