NEW: secondary axes: added functionality to manage additional secondary axes in a JKQTPBasePlotter and to select which x-/y-Axis to use for drawing a JKQTPPlotElement, see also issue #87

This commit is contained in:
jkriege2 2023-03-23 13:55:18 +01:00
parent 8b482a191c
commit f61b46b96b
109 changed files with 1246 additions and 341 deletions

View File

@ -180,6 +180,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
rgbimageplot_qt/rgbimageplot_qt,rgbimageplot_qt_upsidedown/--iteratefunctorsteps rgbimageplot_qt/rgbimageplot_qt,rgbimageplot_qt_upsidedown/--iteratefunctorsteps
mandelbrot mandelbrot
geo_coordinateaxis0 geo_coordinateaxis0
second_axis/second_axis,second_axis_hor
#speed #speed
) )
@ -207,6 +208,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
impulsesplot/JKQTPImpulsesVerticalGraph,JKQTPImpulsesVerticalGraph_Symbols,JKQTPImpulsesHorizontalGraph,JKQTPImpulsesVerticalErrorGraph,JKQTPImpulsesHorizontalErrorGraph,JKQTPImpulsesVerticalGraphNoBaseline,JKQTPImpulsesVerticalGraph_SymbolsNoBaseline,JKQTPImpulsesHorizontalGraphNoBaseline,JKQTPImpulsesVerticalErrorGraphNoBaseline,JKQTPImpulsesHorizontalErrorGraphNoBaseline,JKQTPImpulsesVerticalGraphBaseline,JKQTPImpulsesVerticalGraph_SymbolsBaseline,JKQTPImpulsesHorizontalGraphBaseline,JKQTPImpulsesVerticalErrorGraphBaseline,JKQTPImpulsesHorizontalErrorGraphBaseline/--iteratefunctorsteps--smallscreenshotplot impulsesplot/JKQTPImpulsesVerticalGraph,JKQTPImpulsesVerticalGraph_Symbols,JKQTPImpulsesHorizontalGraph,JKQTPImpulsesVerticalErrorGraph,JKQTPImpulsesHorizontalErrorGraph,JKQTPImpulsesVerticalGraphNoBaseline,JKQTPImpulsesVerticalGraph_SymbolsNoBaseline,JKQTPImpulsesHorizontalGraphNoBaseline,JKQTPImpulsesVerticalErrorGraphNoBaseline,JKQTPImpulsesHorizontalErrorGraphNoBaseline,JKQTPImpulsesVerticalGraphBaseline,JKQTPImpulsesVerticalGraph_SymbolsBaseline,JKQTPImpulsesHorizontalGraphBaseline,JKQTPImpulsesVerticalErrorGraphBaseline,JKQTPImpulsesHorizontalErrorGraphBaseline/--iteratefunctorsteps--smallscreenshotplot
symbols_and_errors/JKQTPXYLineErrorGraph_JKQTPErrorBars,JKQTPXYLineErrorGraph_JKQTPErrorLines,JKQTPXYLineErrorGraph_JKQTPErrorPolygons/--iteratefunctorsteps--iteratefunctorsteps_suppressinitial--smallscreenshotplot symbols_and_errors/JKQTPXYLineErrorGraph_JKQTPErrorBars,JKQTPXYLineErrorGraph_JKQTPErrorLines,JKQTPXYLineErrorGraph_JKQTPErrorPolygons/--iteratefunctorsteps--iteratefunctorsteps_suppressinitial--smallscreenshotplot
boxplot/JKQTPBoxplotVerticalGraph,JKQTPBoxplotHorizontalGraph/--iteratefunctorsteps--iteratefunctorsteps_suppressinitial--smallscreenshotplot boxplot/JKQTPBoxplotVerticalGraph,JKQTPBoxplotHorizontalGraph/--iteratefunctorsteps--iteratefunctorsteps_suppressinitial--smallscreenshotplot
second_axis/JKQTBasePlotter_addSecondaryYAxis,JKQTBasePlotter_addSecondaryXAxis
) )

View File

@ -122,9 +122,12 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
<tr><td> \image html logaxes_small.png <tr><td> \image html logaxes_small.png
<td> \subpage JKQTPlotterLogAxes <td> \subpage JKQTPlotterLogAxes
<td> `JKQTPXYLineGraph` and `JKQTPGeoText` <br> C++ vector of data <br> logarithmic axes and styling <br> plot line styles <br> internal LaTeX parser <br> add commenting text to a graph <td> `JKQTPXYLineGraph` and `JKQTPGeoText` <br> C++ vector of data <br> logarithmic axes and styling <br> plot line styles <br> internal LaTeX parser <br> add commenting text to a graph
<tr><td> \image html dateaxes_timeaxis_small.png <tr><td> \image html dateaxes_timeaxis_small.png
<td> \subpage JKQTPlotterDateTimeAxes <td> \subpage JKQTPlotterDateTimeAxes
<td> `JKQTPXYLineGraph` and `JKQTPFilledVerticalRangeGraph` <br> C++ vector of data <br> date/time axes <br> plot min/max range graph <br> internal LaTeX parser <br> data from CSV files <td> `JKQTPXYLineGraph` and `JKQTPFilledVerticalRangeGraph` <br> C++ vector of data <br> date/time axes <br> plot min/max range graph <br> internal LaTeX parser <br> data from CSV files
<tr><td> \image html second_axis_small.png
<td> \subpage JKQTPlotterSecondaryAxes
<td> plottig with secondary axes, `JKQTPBasePlotter::addSecondaryXAxis()`/`JKQTPBasePlotter::addSecondaryYAxis()`
<tr><td> \image html advancedlineandfillstyling_small.png <tr><td> \image html advancedlineandfillstyling_small.png
<td> \subpage JKQTPlotterAdvancedLineAndFillStyling <td> \subpage JKQTPlotterAdvancedLineAndFillStyling
<td> `JKQTPXYLineGraph`, `JKQTPSpecialLineHorizontalGraph` and `JKQTPBarVerticalGraph` <br> C++ vector of data <br> advanced line styling and filling <td> `JKQTPXYLineGraph`, `JKQTPSpecialLineHorizontalGraph` and `JKQTPBarVerticalGraph` <br> C++ vector of data <br> advanced line styling and filling

View File

@ -18,6 +18,7 @@
derived from JKQTPPlotAnnotationElement derived from JKQTPPlotAnnotationElement
<li> \b key is the legend of the plot, showing a list of the graphs, each represented by a <b>entry marker</b> (showing the graphs color/symbol/...) and a <b>entry title</b>. <li> \b key is the legend of the plot, showing a list of the graphs, each represented by a <b>entry marker</b> (showing the graphs color/symbol/...) and a <b>entry title</b>.
<li> <b>coordinate axis</b> 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 <b>axis label</b>, axis <b> ticks</b> and corresponding <b>tick labels</b> (major and a second set of minor ticks in between are available) <li> <b>coordinate axis</b> 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 <b>axis label</b>, axis <b> ticks</b> and corresponding <b>tick labels</b> (major and a second set of minor ticks in between are available)
<li> <b>secondary coordinate axis</b> you can add additional secondary x- and y-axes to a plot, which are shown stacked, beside the plot.
<li> <b>zero axis</b>: a pair of axes through the origin \c x=0 and \c y=0 of the coordinate system <li> <b>zero axis</b>: a pair of axes through the origin \c x=0 and \c y=0 of the coordinate system
<li> \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 <li> \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
<li> <b>minor grid</b> in addition to the grid, corresponding to the major axis ticks, you can add additional lines that correspond to the minor axis ticks <li> <b>minor grid</b> in addition to the grid, corresponding to the major axis ticks, you can add additional lines that correspond to the minor axis ticks

View File

@ -29,7 +29,6 @@ This page lists several todos and wishes for future version of JKQTPlotter
<li>plot: legend positioning as combination of 3 values: inside|outside + left|center|right + top|vcenter|bottom</li> <li>plot: legend positioning as combination of 3 values: inside|outside + left|center|right + top|vcenter|bottom</li>
<li>plot: refactor print preview/export preview code </li> <li>plot: refactor print preview/export preview code </li>
<li>plot: rework layouting of legends: there are some inconsistencies/too large gaps ...</li> <li>plot: rework layouting of legends: there are some inconsistencies/too large gaps ...</li>
<li>plot: secondary axes: independent and dependent (i.e. with transformation function from primary axis)</li>
<li>sryling: better styling/more styling options for data-tooltips</li> <li>sryling: better styling/more styling options for data-tooltips</li>
<li>styling: color gradients as fill-styles in style-INIs</li> <li>styling: color gradients as fill-styles in style-INIs</li>
<li>styling: style.ini with glowing colors in dark background ("techno" or "cyberpunk")</li> <li>styling: style.ini with glowing colors in dark background ("techno" or "cyberpunk")</li>

View File

@ -67,6 +67,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
<li>NEW: barcharts can be colored by a user-specified functor</li> <li>NEW: barcharts can be colored by a user-specified functor</li>
<li>NEW: you can provide a custom draw functor to barcharts to completely customize their look</li> <li>NEW: you can provide a custom draw functor to barcharts to completely customize their look</li>
<li>NEW: barcharts and impulse graphs may now draw their baseline as stylable line (default: off)</li> <li>NEW: barcharts and impulse graphs may now draw their baseline as stylable line (default: off)</li>
<li>NEW: secondary axes: added functionality to manage additional secondary axes in a JKQTPBasePlotter and to select which x-/y-Axis to use for drawing a JKQTPPlotElement</li>
</ul></li> </ul></li>
<li>JKQTMathText:<ul> <li>JKQTMathText:<ul>

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -91,6 +91,7 @@ add_subdirectory(rgbimageplot_opencv)
add_subdirectory(rgbimageplot_qt) add_subdirectory(rgbimageplot_qt)
add_subdirectory(scatter) add_subdirectory(scatter)
add_subdirectory(scatter_customsymbol) add_subdirectory(scatter_customsymbol)
add_subdirectory(second_axis)
add_subdirectory(speed) add_subdirectory(speed)
add_subdirectory(stackedbars) add_subdirectory(stackedbars)
add_subdirectory(stepplots) add_subdirectory(stepplots)

View File

@ -0,0 +1,34 @@
cmake_minimum_required(VERSION 3.16)
set(EXAMPLE_NAME second_axis)
set(EXENAME jkqtptest_${EXAMPLE_NAME})
message( STATUS ".. Building Example ${EXAMPLE_NAME}" )
# Set up source files
set(SOURCES second_axis.cpp )
set(HEADERS )
set(RESOURCES )
set(UIS )
add_executable(${EXENAME} WIN32 ${SOURCES} ${HEADERS} ${RESOURCES} ${UIS})
target_link_libraries(${EXENAME} JKQTPExampleToolsLib)
target_include_directories(${EXENAME} PRIVATE ../../lib)
if(JKQtPlotter_BUILD_STATIC_LIBS)
target_link_libraries(${EXENAME} JKQTPlotterLib)
elseif(JKQtPlotter_BUILD_SHARED_LIBS)
target_link_libraries(${EXENAME} JKQTPlotterSharedLib)
endif()
# precomiled headers to speed up compilation
if (JKQtPlotter_BUILD_WITH_PRECOMPILED_HEADERS)
target_precompile_headers(${EXENAME} REUSE_FROM jkqtptest_simpletest)
endif (JKQtPlotter_BUILD_WITH_PRECOMPILED_HEADERS)
# Installation
install(TARGETS ${EXENAME} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
#Installation of Qt DLLs on Windows
jkqtplotter_deployqt(${EXENAME})

View File

@ -0,0 +1,135 @@
# Example (JKQTPlotter): Barchart With Two-Color Fill-Mode {#JKQTPlotterBarchartsTwoColorFilling}
This project (see [`second_axis`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/second_axis) shows how to plot with multiple axes.
The source code of the main application is (see [`second_axis.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/second_axis/second_axis.cpp).
In the code we take these step to set up a plot with two secondary axes and three graphs:
1./2. create a plotter and create columns with different dataset:
```.cpp
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
JKQTPDatastore* ds=plot.getDatastore();
// 2. now we create two columns for key and value
size_t columnX=ds->addLinearColumn(40, 0,10,"x");
size_t columnY1=ds->addColumnCalculatedFromColumn(columnX, [](double x) { return x; }, "y1");
size_t columnY2=ds->addColumnCalculatedFromColumn(columnX, [](double x) { return cos(x); }, "y2");
size_t columnY3=ds->addColumnCalculatedFromColumn(columnX, [](double x) { return x*x; }, "y3");
```
3. create a second y-axis and set its formating options, so it only draws an axis on the right
```.cpp
auto yAxisRef2=plot.getPlotter()->addSecondaryYAxis(new JKQTPVerticalAxis(plot.getPlotter(), JKQTPPrimaryAxis));
plot.getYAxis(yAxisRef2)->setDrawGrid(false);
plot.getYAxis(yAxisRef2)->setDrawMode1(JKQTPCADMnone);
plot.getYAxis(yAxisRef2)->setDrawMode2(JKQTPCADMcomplete);
plot.getYAxis(yAxisRef2)->setDrawMode0(JKQTPCADMnone);
plot.getYAxis(yAxisRef2)->setShowZeroAxis(false);
```
... and ctreate third y-axis
```.cpp
auto yAxisRef3=plot.getPlotter()->addSecondaryYAxis(new JKQTPVerticalAxis(plot.getPlotter(), JKQTPPrimaryAxis));
plot.getYAxis(yAxisRef3)->setDrawGrid(false);
plot.getYAxis(yAxisRef3)->setDrawMode1(JKQTPCADMnone);
plot.getYAxis(yAxisRef3)->setDrawMode2(JKQTPCADMcomplete);
plot.getYAxis(yAxisRef3)->setDrawMode0(JKQTPCADMnone);
plot.getYAxis(yAxisRef3)->setShowZeroAxis(false);
```
... reformat the major y-axis, so it does not draw on the right and thus the secondary axis yAxisRef2 replaces it there. If this step is omitted, the secondary axes stack on the right of the primary.
```.cpp
plot.getYAxis()->setDrawMode2(JKQTPCADMnone);
plot.getYAxis()->setColor(graph1->getLineColor());
```
3. create graph in the plot, which plots the dataset:
3.1 the first graph uses the default (primary) x/y-axes
```.cpp
JKQTPXYLineGraph* graph1=new JKQTPXYLineGraph(&plot);
graph1->setKeyColumn(columnX);
graph1->setValueColumn(columnY1);
plot.addGraph(graph1);
plot.getYAxis()->setAxisLabel("graph1");
```
3.2 the second graph uses the default (primary) x-axis, but the secondary axis yAxisRef2 as y-axis
```.cpp
JKQTPXYLineGraph* graph2=new JKQTPXYLineGraph(&plot);
graph2->setKeyColumn(columnX);
graph2->setValueColumn(columnY2);
plot.addGraph(graph2);
```
tell graph2 to use this axis
```.cpp
graph2->setYAxis(yAxisRef2);
```
set axis color to match graph2's color
```.cpp
plot.getYAxis(yAxisRef2)->setColor(graph2->getLineColor());
```
set axis label
```.cpp
plot.getYAxis(yAxisRef2)->setAxisLabel("graph2");
```
3.3 the third graph uses the default (primary) x-axis, but the secondary axis yAxisRef3 as y-axis
```.cpp
JKQTPXYLineGraph* graph3=new JKQTPXYLineGraph(&plot);
graph3->setKeyColumn(columnX);
graph3->setValueColumn(columnY3);
plot.addGraph(graph3);
plot.getYAxis(yAxisRef3)->setColor(graph3->getLineColor());
plot.getYAxis(yAxisRef3)->setAxisLabel("graph3");
graph3->setYAxis(yAxisRef3);
```
4. autoscale the plot so the graph is contained. This auto-scales all axes using the graphs (and their data) as assigned to the axes, i.e.:
- all 3 graphs for x-axis,
- graph1 for primary y-axis,
- graph2 for secondary axis yAxisRef2
- graph3 for secondary axis yAxisRef3
```.cpp
plot.zoomToFit();
```
5. show plotter and make it a decent size
```.cpp
plot.setWindowTitle(title);
plot.show();
plot.resize(500,400);
```
The result looks like this:
![second_axis](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/second_axis.png)
If we set seondary axes for the x-axis instead of the y-axis, i.e. use
```.cpp
// ...
auto xAxisRef2=plot.getPlotter()->addSecondaryXAxis(new JKQTPHorizontalAxis(plot.getPlotter(), JKQTPPrimaryAxis));
// ...
```
we get a plot like this:
![second_axis_hor](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/second_axis_hor.png)

View File

@ -0,0 +1,160 @@
/** \example second_axis.cpp
* Shows how to draw Barcharts with different colors above and below the baseline in a JKQTPlotter
*
* \ref JKQTPlotterSecondaryAxes
*/
#include "jkqtpexampleapplication.h"
#include <QApplication>
#include "jkqtplotter/jkqtplotter.h"
#include "jkqtplotter/graphs/jkqtplines.h"
#include "jkqtpexampleapplication.h"
void exampleSecondYAxis(JKQTPlotter& plot, const QString& title)
{
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
JKQTPDatastore* ds=plot.getDatastore();
// 2. now we create two columns for key and value
size_t columnX=ds->addLinearColumn(40, 0,10,"x");
size_t columnY1=ds->addColumnCalculatedFromColumn(columnX, [](double x) { return x; }, "y1");
size_t columnY2=ds->addColumnCalculatedFromColumn(columnX, [](double x) { return cos(x); }, "y2");
size_t columnY3=ds->addColumnCalculatedFromColumn(columnX, [](double x) { return x*x; }, "y3");
// 3. create a second y-axis and set its formating options, so it only draws an axis on the right
auto yAxisRef2=plot.getPlotter()->addSecondaryYAxis(new JKQTPVerticalAxis(plot.getPlotter(), JKQTPPrimaryAxis));
plot.getYAxis(yAxisRef2)->setDrawGrid(false);
plot.getYAxis(yAxisRef2)->setDrawMode1(JKQTPCADMnone);
plot.getYAxis(yAxisRef2)->setDrawMode2(JKQTPCADMcomplete);
plot.getYAxis(yAxisRef2)->setDrawMode0(JKQTPCADMnone);
plot.getYAxis(yAxisRef2)->setShowZeroAxis(false);
// ... and ctreate third y-axis
auto yAxisRef3=plot.getPlotter()->addSecondaryYAxis(new JKQTPVerticalAxis(plot.getPlotter(), JKQTPPrimaryAxis));
plot.getYAxis(yAxisRef3)->setDrawGrid(false);
plot.getYAxis(yAxisRef3)->setDrawMode1(JKQTPCADMnone);
plot.getYAxis(yAxisRef3)->setDrawMode2(JKQTPCADMcomplete);
plot.getYAxis(yAxisRef3)->setDrawMode0(JKQTPCADMnone);
plot.getYAxis(yAxisRef3)->setShowZeroAxis(false);
// ... reformat the major y-axis, so it does not draw on the right and thus the secondary axis yAxisRef2 replaces it there
// if this step is omitted, the secondary axes stack on the right of the primary.
plot.getYAxis()->setDrawMode2(JKQTPCADMnone);
plot.getYAxis()->setAxisLabel("graph1");
// 3. create graph in the plot, which plots the dataset:
// 3.1 the first graph uses the default (primary) x/y-axes
JKQTPXYLineGraph* graph1=new JKQTPXYLineGraph(&plot);
graph1->setKeyColumn(columnX);
graph1->setValueColumn(columnY1);
plot.addGraph(graph1);
plot.getYAxis()->setColor(graph1->getLineColor());
// 3.2 the second graph uses the default (primary) x-axis, but the secondary axis yAxisRef2 as y-axis
JKQTPXYLineGraph* graph2=new JKQTPXYLineGraph(&plot);
graph2->setKeyColumn(columnX);
graph2->setValueColumn(columnY2);
plot.addGraph(graph2);
// tell graph2 to use this axis
graph2->setYAxis(yAxisRef2);
// set axis color to match graph2's color
plot.getYAxis(yAxisRef2)->setColor(graph2->getLineColor());
// set axis label
plot.getYAxis(yAxisRef2)->setAxisLabel("graph2");
// 3.3 the third graph uses the default (primary) x-axis, but the secondary axis yAxisRef3 as y-axis
JKQTPXYLineGraph* graph3=new JKQTPXYLineGraph(&plot);
graph3->setKeyColumn(columnX);
graph3->setValueColumn(columnY3);
plot.addGraph(graph3);
plot.getYAxis(yAxisRef3)->setColor(graph3->getLineColor());
plot.getYAxis(yAxisRef3)->setAxisLabel("graph3");
graph3->setYAxis(yAxisRef3);
// 4. autoscale the plot so the graph is contained
// This auto-scales all axes using the graphs (and their data) as assigned to the axes!
// i.e. all 3 graphs for x-axis,
// graph1 for primary y-axis,
// graph2 for secondary axis yAxisRef2
// graph3 for secondary axis yAxisRef3
plot.zoomToFit();
// 5. show plotter and make it a decent size
plot.setWindowTitle(title);
plot.show();
plot.resize(500,400);
}
void exampleSecondXAxis(JKQTPlotter& plot, const QString& title)
{
// same as above, but with swapped x- and y-axes!!!
JKQTPDatastore* ds=plot.getDatastore();
size_t columnY=ds->addLinearColumn(30, 0,12,"y");
size_t columnX1=ds->addColumnCalculatedFromColumn(columnY, [](double x) { return x; }, "x1");
size_t columnX2=ds->addColumnCalculatedFromColumn(columnY, [](double x) { return cos(x); }, "x2");
size_t columnX3=ds->addColumnCalculatedFromColumn(columnY, [](double x) { return x*x; }, "x3");
JKQTPXYLineGraph* graph1=new JKQTPXYLineGraph(&plot);
graph1->setXColumn(columnX1);
graph1->setYColumn(columnY);
plot.addGraph(graph1);
JKQTPXYLineGraph* graph2=new JKQTPXYLineGraph(&plot);
graph2->setXColumn(columnX2);
graph2->setYColumn(columnY);
plot.addGraph(graph2);
JKQTPXYLineGraph* graph3=new JKQTPXYLineGraph(&plot);
graph3->setXColumn(columnX3);
graph3->setYColumn(columnY);
plot.addGraph(graph3);
plot.getXAxis()->setDrawMode2(JKQTPCADMLineTicksTickLabels);
plot.getXAxis()->setColor(graph1->getLineColor());
plot.getXAxis()->setAxisLabel("graph1");
auto xAxisRef2=plot.getPlotter()->addSecondaryXAxis(new JKQTPHorizontalAxis(plot.getPlotter(), JKQTPPrimaryAxis));
plot.getXAxis(xAxisRef2)->setDrawGrid(false);
plot.getXAxis(xAxisRef2)->setDrawMode1(JKQTPCADMnone);
plot.getXAxis(xAxisRef2)->setDrawMode2(JKQTPCADMcomplete);
plot.getXAxis(xAxisRef2)->setDrawMode0(JKQTPCADMnone);
plot.getXAxis(xAxisRef2)->setShowZeroAxis(false);
plot.getXAxis(xAxisRef2)->setColor(graph2->getLineColor());
plot.getXAxis(xAxisRef2)->setAxisLabel("graph2");
graph2->setXAxis(xAxisRef2);
auto xAxisRef3=plot.getPlotter()->addSecondaryXAxis(new JKQTPHorizontalAxis(plot.getPlotter(), JKQTPPrimaryAxis));
plot.getXAxis(xAxisRef3)->setDrawGrid(false);
plot.getXAxis(xAxisRef3)->setDrawMode1(JKQTPCADMnone);
plot.getXAxis(xAxisRef3)->setDrawMode2(JKQTPCADMcomplete);
plot.getXAxis(xAxisRef3)->setDrawMode0(JKQTPCADMnone);
plot.getXAxis(xAxisRef3)->setShowZeroAxis(false);
plot.getXAxis(xAxisRef3)->setColor(graph3->getLineColor());
plot.getXAxis(xAxisRef3)->setAxisLabel("graph3");
graph3->setXAxis(xAxisRef3);
plot.zoomToFit();
plot.setWindowTitle(title);
plot.show();
plot.resize(400,500);
}
int main(int argc, char* argv[])
{
JKQTPAppSettingController highDPIController(argc,argv);
JKQTPExampleApplication app(argc, argv);
JKQTPlotter plotsecondY;
exampleSecondYAxis(plotsecondY, "1: Second Y-Axis");
JKQTPlotter plotsecondX;
exampleSecondXAxis(plotsecondX, "2: Second X-Axis");
return app.exec();
}

View File

@ -115,7 +115,7 @@ if(JKQtPlotter_BUILD_STATIC_LIBS)
write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${lib_name}Version.cmake write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${lib_name}Version.cmake
VERSION ${PROJECT_VERSION} VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion ) COMPATIBILITY AnyNewerVersion )
add_library(${oldlib_name} ALIAS ${oldlib_name}) add_library(${oldlib_name} ALIAS ${lib_name})
endif() endif()

View File

@ -68,9 +68,9 @@ void JKQTPBarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
// double x0=transformX(0); // double x0=transformX(0);
// if (parent->getXAxis()->isLogAxis()) x0=transformX(parent->getXAxis()->getMin()); // if (getXAxis()->isLogAxis()) x0=transformX(getXAxis()->getMin());
double y0=transformY(0); double y0=transformY(0);
if (parent->getYAxis()->isLogAxis()) y0=transformY(parent->getYAxis()->getMin()); if (getYAxis()->isLogAxis()) y0=transformY(getYAxis()->getMin());
double delta=1; double delta=1;
double deltap=0; double deltap=0;
double deltam=0; double deltam=0;
@ -248,9 +248,9 @@ void JKQTPBarHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
if (getIndexRange(imin, imax)) { if (getIndexRange(imin, imax)) {
double x0=transformX(0); double x0=transformX(0);
if (parent->getXAxis()->isLogAxis()) x0=transformX(parent->getXAxis()->getMin()); if (getXAxis()->isLogAxis()) x0=transformX(getXAxis()->getMin());
// double y0=transformY(0); // double y0=transformY(0);
// if (parent->getYAxis()->isLogAxis()) y0=transformY(parent->getYAxis()->getMin()); // if (getYAxis()->isLogAxis()) y0=transformY(getYAxis()->getMin());
{ {
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
intSortData(); intSortData();

View File

@ -224,12 +224,12 @@ void JKQTPEvaluatedFunctionWithErrorsGraphDrawingBase::drawXGraph(JKQTPEnhancedP
double y0=transformY(0); double y0=transformY(0);
if (parent->getYAxis()->isLogAxis()) y0=transformY(parent->getYAxis()->getMin()); if (getYAxis()->isLogAxis()) y0=transformY(getYAxis()->getMin());
bool first=false; bool first=false;
QPolygonF filledPolygon, linePolygon, errorLineTop, errorLineBottom; QPolygonF filledPolygon, linePolygon, errorLineTop, errorLineBottom;
QList<QPointF> epTop, epBottom; QList<QPointF> epTop, epBottom;
double yami=qMin(transformY(parent->getYAxis()->getMin()),transformY(parent->getYAxis()->getMax())); double yami=qMin(transformY(getYAxis()->getMin()),transformY(getYAxis()->getMax()));
double yama=qMax(transformY(parent->getYAxis()->getMin()),transformY(parent->getYAxis()->getMax())); double yama=qMax(transformY(getYAxis()->getMin()),transformY(getYAxis()->getMax()));
double dypix=fabs(yama-yami); double dypix=fabs(yama-yami);
yami=yami-2.0*dypix; yami=yami-2.0*dypix;
yama=yama+2.0*dypix; yama=yama+2.0*dypix;
@ -351,12 +351,12 @@ void JKQTPEvaluatedFunctionWithErrorsGraphDrawingBase::drawYGraph(JKQTPEnhancedP
double x0=transformX(0); double x0=transformX(0);
if (parent->getXAxis()->isLogAxis()) x0=transformX(parent->getXAxis()->getMin()); if (getXAxis()->isLogAxis()) x0=transformX(getXAxis()->getMin());
bool first=false; bool first=false;
QPolygonF filledPolygon, linePolygon, errorLineTop, errorLineBottom; QPolygonF filledPolygon, linePolygon, errorLineTop, errorLineBottom;
QList<QPointF> epTop, epBottom; QList<QPointF> epTop, epBottom;
double xami=qMin(transformY(parent->getXAxis()->getMin()),transformY(parent->getXAxis()->getMax())); double xami=qMin(transformY(getXAxis()->getMin()),transformY(getXAxis()->getMax()));
double xama=qMax(transformY(parent->getXAxis()->getMin()),transformY(parent->getXAxis()->getMax())); double xama=qMax(transformY(getXAxis()->getMin()),transformY(getXAxis()->getMax()));
double dxpix=fabs(xama-xami); double dxpix=fabs(xama-xami);
xami=xami-2.0*dxpix; xami=xami-2.0*dxpix;
xama=xama+2.0*dxpix; xama=xama+2.0*dxpix;

View File

@ -146,10 +146,10 @@ void JKQTPFilledCurveXGraph::draw(JKQTPEnhancedPainter& painter) {
double xold=-1; double xold=-1;
//double yold=-1; //double yold=-1;
double y0=transformY(getBaseline()); double y0=transformY(getBaseline());
if (parent->getYAxis()->isLogAxis()) { if (getYAxis()->isLogAxis()) {
y0=transformY(parent->getYAxis()->getMin()); y0=transformY(getYAxis()->getMin());
if (getBaseline()>0 && getBaseline()>parent->getYAxis()->getMin()) y0=transformY(getBaseline()); if (getBaseline()>0 && getBaseline()>getYAxis()->getMin()) y0=transformY(getBaseline());
else y0=transformY(parent->getYAxis()->getMin()); else y0=transformY(getYAxis()->getMin());
} }
bool subsequentItem=false; bool subsequentItem=false;
intSortData(); intSortData();
@ -270,9 +270,9 @@ void JKQTPFilledCurveYGraph::draw(JKQTPEnhancedPainter &painter)
//double xold=-1; //double xold=-1;
double yold=-1; double yold=-1;
double x0=transformX(getBaseline()); double x0=transformX(getBaseline());
if (parent->getXAxis()->isLogAxis()) { if (getXAxis()->isLogAxis()) {
if (getBaseline()>0 && getBaseline()>parent->getXAxis()->getMin()) x0=transformX(getBaseline()); if (getBaseline()>0 && getBaseline()>getXAxis()->getMin()) x0=transformX(getBaseline());
else x0=transformX(parent->getXAxis()->getMin()); else x0=transformX(getXAxis()->getMin());
} }
bool first=false; bool first=false;
intSortData(); intSortData();

View File

@ -104,7 +104,7 @@ void JKQTPGeoLine::draw(JKQTPEnhancedPainter& painter) {
QPointF xx2(transformX(x2), transformY(y2)); QPointF xx2(transformX(x2), transformY(y2));
if ( QLineF(xx1, xx2).length()>0) { if ( QLineF(xx1, xx2).length()>0) {
if ((getDrawMode()==DrawAsGraphicElement) || (getParent()->getXAxis()->isLinearAxis() && getParent()->getYAxis()->isLinearAxis())) { if ((getDrawMode()==DrawAsGraphicElement) || (getXAxis()->isLinearAxis() && getYAxis()->isLinearAxis())) {
// for linear axes, we can simply draw a line // for linear axes, we can simply draw a line
const double angle1=atan2(xx2.y()-xx1.y(), xx2.x()-xx1.x()); const double angle1=atan2(xx2.y()-xx1.y(), xx2.x()-xx1.x());
const double angle2=atan2(xx1.y()-xx2.y(), xx1.x()-xx2.x()); const double angle2=atan2(xx1.y()-xx2.y(), xx1.x()-xx2.x());
@ -115,10 +115,10 @@ void JKQTPGeoLine::draw(JKQTPEnhancedPainter& painter) {
painter.drawLine(QLineF(lx1, lx2)); painter.drawLine(QLineF(lx1, lx2));
} else { } else {
QLineF line(QPointF(x1,y1), QPointF(x2,y2)); QLineF line(QPointF(x1,y1), QPointF(x2,y2));
const double xmin=parent->getXAxis()->getMin(); const double xmin=getXAxis()->getMin();
const double xmax=parent->getXAxis()->getMax(); const double xmax=getXAxis()->getMax();
const double ymin=parent->getYAxis()->getMin(); const double ymin=getYAxis()->getMin();
const double ymax=parent->getYAxis()->getMax(); const double ymax=getYAxis()->getMax();
const QRectF bbox(QPointF(xmin, ymin), QPointF(xmax, ymax)); const QRectF bbox(QPointF(xmin, ymin), QPointF(xmax, ymax));
bool drawHead=bbox.contains(line.p2()); bool drawHead=bbox.contains(line.p2());
bool drawTail=bbox.contains(line.p1()); bool drawTail=bbox.contains(line.p1());
@ -283,10 +283,10 @@ void JKQTPGeoInfiniteLine::draw(JKQTPEnhancedPainter& painter) {
clearHitTestData(); clearHitTestData();
reserveHitTestData(2); reserveHitTestData(2);
double xmin=parent->getXAxis()->getMin(); double xmin=getXAxis()->getMin();
double xmax=parent->getXAxis()->getMax(); double xmax=getXAxis()->getMax();
double ymin=parent->getYAxis()->getMin(); double ymin=getYAxis()->getMin();
double ymax=parent->getYAxis()->getMax(); double ymax=getYAxis()->getMax();
QRectF bbox(QPointF(xmin, ymin), QPointF(xmax, ymax)); QRectF bbox(QPointF(xmin, ymin), QPointF(xmax, ymax));
bool doDraw=false; bool doDraw=false;
double x2=x, y2=y; double x2=x, y2=y;
@ -404,7 +404,7 @@ void JKQTPGeoInfiniteLine::draw(JKQTPEnhancedPainter& painter) {
if (line.length()>0) { if (line.length()>0) {
QPointF xx1; QPointF xx1;
double angle1=0; double angle1=0;
if ((getDrawMode()==DrawAsGraphicElement) || (getParent()->getXAxis()->isLinearAxis() && getParent()->getYAxis()->isLinearAxis())) { if ((getDrawMode()==DrawAsGraphicElement) || (getXAxis()->isLinearAxis() && getYAxis()->isLinearAxis())) {
painter.drawLine(line); painter.drawLine(line);
xx1=QPointF(transformX(x),transformY(y)); xx1=QPointF(transformX(x),transformY(y));
angle1=atan2(line.dy(), line.dx()); angle1=atan2(line.dy(), line.dx());
@ -579,7 +579,7 @@ void JKQTPGeoPolyLines::draw(JKQTPEnhancedPainter& painter) {
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setPen(getLinePen(painter, parent)); painter.setPen(getLinePen(painter, parent));
painter.setBrush(getLineColor()); painter.setBrush(getLineColor());
if ((getDrawMode()==DrawAsGraphicElement) || (getParent()->getXAxis()->isLinearAxis() && getParent()->getYAxis()->isLinearAxis())) { if ((getDrawMode()==DrawAsGraphicElement) || (getXAxis()->isLinearAxis() && getYAxis()->isLinearAxis())) {
QVector<QPointF> path=transform(points); QVector<QPointF> path=transform(points);
angle1=atan2(path[1].y()-path[0].y(), path[1].x()-path[0].x()); angle1=atan2(path[1].y()-path[0].y(), path[1].x()-path[0].x());
angle2=atan2(path[path.size()-2].y()-path[path.size()-1].y(), path[path.size()-2].x()-path[path.size()-1].x()); angle2=atan2(path[path.size()-2].y()-path[path.size()-1].y(), path[path.size()-2].x()-path[path.size()-1].x());

View File

@ -132,7 +132,7 @@ void JKQTPGeoRectangle::draw(JKQTPEnhancedPainter& painter) {
QPolygonF poly=getPolygon(); QPolygonF poly=getPolygon();
reserveHitTestData(poly.size()); reserveHitTestData(poly.size());
QPolygonF rect; QPolygonF rect;
if ((getDrawMode()==DrawAsGraphicElement) || (getParent()->getXAxis()->isLinearAxis() && getParent()->getYAxis()->isLinearAxis())) { if ((getDrawMode()==DrawAsGraphicElement) || (getXAxis()->isLinearAxis() && getYAxis()->isLinearAxis())) {
rect=transform(poly); rect=transform(poly);
} else { } else {
auto fTransform=std::bind([](const JKQTPGeometricPlotElement* plot, const QPointF& p) { return plot->transform(p); }, this, std::placeholders::_1); auto fTransform=std::bind([](const JKQTPGeometricPlotElement* plot, const QPointF& p) { return plot->transform(p); }, this, std::placeholders::_1);
@ -313,7 +313,7 @@ void JKQTPGeoPolygon::draw(JKQTPEnhancedPainter& painter) {
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
painter.setPen(getLinePen(painter, parent)); painter.setPen(getLinePen(painter, parent));
painter.setBrush(getFillBrush(painter, parent)); painter.setBrush(getFillBrush(painter, parent));
if ((getDrawMode()==DrawAsGraphicElement) || (getParent()->getXAxis()->isLinearAxis() && getParent()->getYAxis()->isLinearAxis())) { if ((getDrawMode()==DrawAsGraphicElement) || (getXAxis()->isLinearAxis() && getYAxis()->isLinearAxis())) {
painter.drawPolygon(transform(points)); painter.drawPolygon(transform(points));
} else { } else {
// for non-linear axes, a line might not be drawn as a line, so we need to segment the line (i.e. linear function in coordinate space) // for non-linear axes, a line might not be drawn as a line, so we need to segment the line (i.e. linear function in coordinate space)

View File

@ -206,9 +206,9 @@ void JKQTPImpulsesHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
if (getIndexRange(imin, imax)) { if (getIndexRange(imin, imax)) {
double x0=transformX(getBaseline()); double x0=transformX(getBaseline());
if (parent->getXAxis()->isLogAxis()) { if (getXAxis()->isLogAxis()) {
if (getBaseline()>0 && getBaseline()>parent->getXAxis()->getMin()) x0=transformX(getBaseline()); if (getBaseline()>0 && getBaseline()>getXAxis()->getMin()) x0=transformX(getBaseline());
else x0=transformX(parent->getXAxis()->getMin()); else x0=transformX(getXAxis()->getMin());
} }
QVector<QLineF> lines; QVector<QLineF> lines;
@ -364,9 +364,9 @@ void JKQTPImpulsesVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
double y0=transformY(getBaseline()); double y0=transformY(getBaseline());
if (parent->getYAxis()->isLogAxis()) { if (getYAxis()->isLogAxis()) {
if (getBaseline()>0 && getBaseline()>parent->getYAxis()->getMin()) y0=transformY(getBaseline()); if (getBaseline()>0 && getBaseline()>getYAxis()->getMin()) y0=transformY(getBaseline());
else y0=transformY(parent->getYAxis()->getMin()); else y0=transformY(getYAxis()->getMin());
} }
QVector<QLineF> lines; QVector<QLineF> lines;
QVector<QPointF> points; QVector<QPointF> points;

View File

@ -78,10 +78,10 @@ void JKQTPXYLineGraph::draw(JKQTPEnhancedPainter& painter) {
const QPen p=getLinePen(painter, parent); const QPen p=getLinePen(painter, parent);
const QPen penSelection=getHighlightingLinePen(painter, parent); const QPen penSelection=getHighlightingLinePen(painter, parent);
const auto symType=getSymbolType(); const auto symType=getSymbolType();
const double xmin=transformX(parent->getXAxis()->getMin()); const double xmin=transformX(getXAxis()->getMin());
const double xmax=transformX(parent->getXAxis()->getMax()); const double xmax=transformX(getXAxis()->getMax());
const double ymin=transformY(parent->getYAxis()->getMin()); const double ymin=transformY(getYAxis()->getMin());
const double ymax=transformY(parent->getYAxis()->getMax()); const double ymax=transformY(getYAxis()->getMax());
const double symbolSize=parent->pt2px(painter, getSymbolSize()); const double symbolSize=parent->pt2px(painter, getSymbolSize());
const QMarginsF clipMargins=(symType==JKQTPNoSymbol)?QMarginsF(0,0,0,0):QMarginsF(symbolSize,symbolSize,symbolSize,symbolSize); const QMarginsF clipMargins=(symType==JKQTPNoSymbol)?QMarginsF(0,0,0,0):QMarginsF(symbolSize,symbolSize,symbolSize,symbolSize);
const QRectF cliprect=QRectF(qMin(xmin,xmax),qMin(ymin,ymax),fabs(xmax-xmin),fabs(ymax-ymin))+clipMargins; const QRectF cliprect=QRectF(qMin(xmin,xmax),qMin(ymin,ymax),fabs(xmax-xmin),fabs(ymax-ymin))+clipMargins;
@ -108,7 +108,7 @@ void JKQTPXYLineGraph::draw(JKQTPEnhancedPainter& painter) {
//if (isHighlighted() && getSymbolType()!=JKQTPNoSymbol) { //if (isHighlighted() && getSymbolType()!=JKQTPNoSymbol) {
//JKQTPPlotSymbol(painter, x, y, JKQTPFilledCircle, parent->pt2px(painter, symbolSize*1.5), parent->pt2px(painter, symbolWidth*parent->getLineWidthMultiplier()), penSelection.color(), penSelection.color(),getSymbolFont()); //JKQTPPlotSymbol(painter, x, y, JKQTPFilledCircle, parent->pt2px(painter, symbolSize*1.5), parent->pt2px(painter, symbolWidth*parent->getLineWidthMultiplier()), penSelection.color(), penSelection.color(),getSymbolFont());
//} //}
if ((!parent->getXAxis()->isLogAxis() || xv>0.0) && (!parent->getYAxis()->isLogAxis() || yv>0.0) ) { if ((!getXAxis()->isLogAxis() || xv>0.0) && (!getYAxis()->isLogAxis() || yv>0.0) ) {
if (symType!=JKQTPNoSymbol && cliprect.contains(x,y)) { if (symType!=JKQTPNoSymbol && cliprect.contains(x,y)) {
if (drawLineInForeground) plotStyledSymbol(parent, painter, x, y); if (drawLineInForeground) plotStyledSymbol(parent, painter, x, y);
else symbols.push_back({x,y}); else symbols.push_back({x,y});

View File

@ -255,10 +255,10 @@ void JKQTPHorizontalRange::draw(JKQTPEnhancedPainter& painter) {
double c=transformY(rangeCenter); double c=transformY(rangeCenter);
double cmi=transformY(rangeMin); double cmi=transformY(rangeMin);
double cma=transformY(rangeMax); double cma=transformY(rangeMax);
double smi=transformY(parent->getYAxis()->getMin()); double smi=transformY(getYAxis()->getMin());
double sma=transformY(parent->getYAxis()->getMax()); double sma=transformY(getYAxis()->getMax());
double mi=transformX(parent->getXAxis()->getMin()); double mi=transformX(getXAxis()->getMin());
double ma=transformX(parent->getXAxis()->getMax()); double ma=transformX(getXAxis()->getMax());
if (!unlimitedSizeMin) mi=transformX(sizeMin); if (!unlimitedSizeMin) mi=transformX(sizeMin);
if (!unlimitedSizeMax) ma=transformX(sizeMax); if (!unlimitedSizeMax) ma=transformX(sizeMax);
//std::cout<<"hor: rangeMin="<<rangeMin<<" -> "<<cmi<<std::endl; //std::cout<<"hor: rangeMin="<<rangeMin<<" -> "<<cmi<<std::endl;
@ -380,10 +380,10 @@ void JKQTPVerticalRange::draw(JKQTPEnhancedPainter& painter) {
double c=transformX(rangeCenter); double c=transformX(rangeCenter);
double cmi=transformX(rangeMin); double cmi=transformX(rangeMin);
double cma=transformX(rangeMax); double cma=transformX(rangeMax);
double mi=transformY(parent->getYAxis()->getMin()); double mi=transformY(getYAxis()->getMin());
double ma=transformY(parent->getYAxis()->getMax()); double ma=transformY(getYAxis()->getMax());
double smi=transformX(parent->getXAxis()->getMin()); double smi=transformX(getXAxis()->getMin());
double sma=transformX(parent->getXAxis()->getMax()); double sma=transformX(getXAxis()->getMax());
if (!unlimitedSizeMin) mi=transformY(sizeMin); if (!unlimitedSizeMin) mi=transformY(sizeMin);
if (!unlimitedSizeMax) ma=transformY(sizeMax); if (!unlimitedSizeMax) ma=transformY(sizeMax);
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});

View File

@ -78,10 +78,10 @@ void JKQTPXYScatterGraph::draw(JKQTPEnhancedPainter& painter) {
//qDebug()<<"JKQTPXYScatterGraph::draw(): "<<2; //qDebug()<<"JKQTPXYScatterGraph::draw(): "<<2;
const auto symType=getSymbolType(); const auto symType=getSymbolType();
const double xmin=transformX(parent->getXAxis()->getMin()); const double xmin=transformX(getXAxis()->getMin());
const double xmax=transformX(parent->getXAxis()->getMax()); const double xmax=transformX(getXAxis()->getMax());
const double ymin=transformY(parent->getYAxis()->getMin()); const double ymin=transformY(getYAxis()->getMin());
const double ymax=transformY(parent->getYAxis()->getMax()); const double ymax=transformY(getYAxis()->getMax());
const double symbolSize=parent->pt2px(painter, getSymbolSize()); const double symbolSize=parent->pt2px(painter, getSymbolSize());
const QMarginsF clipMargins=(symType==JKQTPNoSymbol)?QMarginsF(0,0,0,0):QMarginsF(symbolSize,symbolSize,symbolSize,symbolSize); const QMarginsF clipMargins=(symType==JKQTPNoSymbol)?QMarginsF(0,0,0,0):QMarginsF(symbolSize,symbolSize,symbolSize,symbolSize);
const QRectF cliprect=QRectF(qMin(xmin,xmax),qMin(ymin,ymax),fabs(xmax-xmin),fabs(ymax-ymin))+clipMargins; const QRectF cliprect=QRectF(qMin(xmin,xmax),qMin(ymin,ymax),fabs(xmax-xmin),fabs(ymax-ymin))+clipMargins;
@ -102,7 +102,7 @@ void JKQTPXYScatterGraph::draw(JKQTPEnhancedPainter& painter) {
//if (isHighlighted() && getSymbolType()!=JKQTPNoSymbol) { //if (isHighlighted() && getSymbolType()!=JKQTPNoSymbol) {
//JKQTPPlotSymbol(painter, x, y, JKQTPFilledCircle, parent->pt2px(painter, symbolSize*1.5), parent->pt2px(painter, symbolWidth*parent->getLineWidthMultiplier()), penSelection.color(), penSelection.color()); //JKQTPPlotSymbol(painter, x, y, JKQTPFilledCircle, parent->pt2px(painter, symbolSize*1.5), parent->pt2px(painter, symbolWidth*parent->getLineWidthMultiplier()), penSelection.color(), penSelection.color());
//} //}
if ((!parent->getXAxis()->isLogAxis() || xv>0.0) && (!parent->getYAxis()->isLogAxis() || yv>0.0) ) { if ((!getXAxis()->isLogAxis() || xv>0.0) && (!getYAxis()->isLogAxis() || yv>0.0) ) {
if (symType!=JKQTPNoSymbol && cliprect.contains(x,y)) plotStyledSymbol(parent, painter, x, y); if (symType!=JKQTPNoSymbol && cliprect.contains(x,y)) plotStyledSymbol(parent, painter, x, y);
} }
} }
@ -364,7 +364,7 @@ void JKQTPXYParametrizedScatterGraph::draw(JKQTPEnhancedPainter &painter)
linewidths<<lineW; linewidths<<lineW;
} }
if ((!parent->getXAxis()->isLogAxis() || xv>0.0) && (!parent->getYAxis()->isLogAxis() || yv>0.0) ) { if ((!getXAxis()->isLogAxis() || xv>0.0) && (!getYAxis()->isLogAxis() || yv>0.0) ) {
if (isHighlighted() && getSymbolType()!=JKQTPNoSymbol && symbolColumn<0) { if (isHighlighted() && getSymbolType()!=JKQTPNoSymbol && symbolColumn<0) {
JKQTPPlotSymbol(painter, x, y, JKQTPFilledCircle,symbSize*1.25, parent->pt2px(painter, getSymbolLineWidth()*parent->getLineWidthMultiplier()), penSelection.color(), penSelection.color(),getSymbolFont()); JKQTPPlotSymbol(painter, x, y, JKQTPFilledCircle,symbSize*1.25, parent->pt2px(painter, getSymbolLineWidth()*parent->getLineWidthMultiplier()), penSelection.color(), penSelection.color(),getSymbolFont());
} else { } else {

View File

@ -128,10 +128,10 @@ void JKQTPSpecialLineHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
QPen ph=getHighlightingLinePen(painter, parent); QPen ph=getHighlightingLinePen(painter, parent);
QPen np(Qt::NoPen); QPen np(Qt::NoPen);
QBrush b=getFillBrush(painter, parent); QBrush b=getFillBrush(painter, parent);
const double xmin=transformX(parent->getXAxis()->getMin()); const double xmin=transformX(getXAxis()->getMin());
const double xmax=transformX(parent->getXAxis()->getMax()); const double xmax=transformX(getXAxis()->getMax());
const double ymin=transformY(parent->getYAxis()->getMin()); const double ymin=transformY(getYAxis()->getMin());
const double ymax=transformY(parent->getYAxis()->getMax()); const double ymax=transformY(getYAxis()->getMax());
const auto symType=getSymbolType(); const auto symType=getSymbolType();
const double symbolSize=parent->pt2px(painter, getSymbolSize()); const double symbolSize=parent->pt2px(painter, getSymbolSize());
const QMarginsF clipMargins=(symType==JKQTPNoSymbol)?QMarginsF(0,0,0,0):QMarginsF(symbolSize,symbolSize,symbolSize,symbolSize); const QMarginsF clipMargins=(symType==JKQTPNoSymbol)?QMarginsF(0,0,0,0):QMarginsF(symbolSize,symbolSize,symbolSize,symbolSize);
@ -149,9 +149,9 @@ void JKQTPSpecialLineHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
double xold=-1; double xold=-1;
double yold=-1; double yold=-1;
double y0=transformY(getBaseline()); double y0=transformY(getBaseline());
if (parent->getYAxis()->isLogAxis()) { if (getYAxis()->isLogAxis()) {
if (getBaseline()>0 && getBaseline()>parent->getYAxis()->getMin()) y0=transformY(getBaseline()); if (getBaseline()>0 && getBaseline()>getYAxis()->getMin()) y0=transformY(getBaseline());
else y0=transformY(parent->getYAxis()->getMin()); else y0=transformY(getYAxis()->getMin());
} }
bool firstPoint=true; bool firstPoint=true;
intSortData(); intSortData();
@ -336,10 +336,10 @@ void JKQTPSpecialLineVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
QPen ph=getHighlightingLinePen(painter, parent); QPen ph=getHighlightingLinePen(painter, parent);
QPen np(Qt::NoPen); QPen np(Qt::NoPen);
QBrush b=getFillBrush(painter, parent); QBrush b=getFillBrush(painter, parent);
const double xmin=transformX(parent->getXAxis()->getMin()); const double xmin=transformX(getXAxis()->getMin());
const double xmax=transformX(parent->getXAxis()->getMax()); const double xmax=transformX(getXAxis()->getMax());
const double ymin=transformY(parent->getYAxis()->getMin()); const double ymin=transformY(getYAxis()->getMin());
const double ymax=transformY(parent->getYAxis()->getMax()); const double ymax=transformY(getYAxis()->getMax());
const auto symType=getSymbolType(); const auto symType=getSymbolType();
const double symbolSize=parent->pt2px(painter, getSymbolSize()); const double symbolSize=parent->pt2px(painter, getSymbolSize());
const QMarginsF clipMargins=(symType==JKQTPNoSymbol)?QMarginsF(0,0,0,0):QMarginsF(symbolSize,symbolSize,symbolSize,symbolSize); const QMarginsF clipMargins=(symType==JKQTPNoSymbol)?QMarginsF(0,0,0,0):QMarginsF(symbolSize,symbolSize,symbolSize,symbolSize);
@ -357,9 +357,9 @@ void JKQTPSpecialLineVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
double xold=-1; double xold=-1;
double yold=-1; double yold=-1;
double x0=transformX(getBaseline()); double x0=transformX(getBaseline());
if (parent->getXAxis()->isLogAxis()) { if (getXAxis()->isLogAxis()) {
if (getBaseline()>0 && getBaseline()>parent->getXAxis()->getMin()) x0=transformX(getBaseline()); if (getBaseline()>0 && getBaseline()>getXAxis()->getMin()) x0=transformX(getBaseline());
else x0=transformX(parent->getXAxis()->getMin()); else x0=transformX(getXAxis()->getMin());
} }
bool first=false; bool first=false;
intSortData(); intSortData();

View File

@ -48,16 +48,10 @@
#ifdef QFWIDLIB_LIBRARY #ifdef QFWIDLIB_LIBRARY
# include "qftools.h" # include "qftools.h"
#endif #endif
#include "jkqtplotter/graphs/jkqtpboxplot.h"
#include "jkqtplotter/graphs/jkqtpbarchart.h"
#include "jkqtplotter/graphs/jkqtpfilledcurve.h"
#include "jkqtplotter/graphs/jkqtpspecialline.h"
#include "jkqtplotter/graphs/jkqtpimpulses.h"
#include "jkqtplotter/graphs/jkqtpscatter.h"
#include "jkqtplotter/graphs/jkqtpgeometric.h"
#include "jkqtplotter/graphs/jkqtpimage.h" #include "jkqtplotter/graphs/jkqtpimage.h"
#include "jkqtplotter/graphs/jkqtpimagergb.h" #include "jkqtplotter/graphs/jkqtpimagergb.h"
#include "jkqtmathtext/jkqtmathtext.h" #include "jkqtmathtext/jkqtmathtext.h"
#include <algorithm>
static QString globalUserSettigsFilename=""; static QString globalUserSettigsFilename="";
static QString globalUserSettigsPrefix=""; static QString globalUserSettigsPrefix="";
@ -302,6 +296,15 @@ JKQTBasePlotter::~JKQTBasePlotter(){
if (datastoreInternal && datastore!=nullptr) delete datastore; if (datastoreInternal && datastore!=nullptr) delete datastore;
delete xAxis; delete xAxis;
delete yAxis; delete yAxis;
for (const auto& ax: qAsConst(secondaryYAxis)) {
delete ax;
}
secondaryYAxis.clear();
for (const auto& ax: qAsConst(secondaryXAxis)) {
delete ax;
}
secondaryXAxis.clear();
} }
void JKQTBasePlotter::setGrid(bool val) { void JKQTBasePlotter::setGrid(bool val) {
@ -345,8 +348,8 @@ void JKQTBasePlotter::setMinorGridStyle(Qt::PenStyle __value)
} }
void JKQTBasePlotter::setShowZeroAxes(bool showX, bool showY) { void JKQTBasePlotter::setShowZeroAxes(bool showX, bool showY) {
getXAxis()->setShowZeroAxis(showX); xAxis->setShowZeroAxis(showX);
getYAxis()->setShowZeroAxis(showY); yAxis->setShowZeroAxis(showY);
} }
void JKQTBasePlotter::setShowZeroAxes(bool showXY) { void JKQTBasePlotter::setShowZeroAxes(bool showXY) {
@ -410,10 +413,10 @@ void JKQTBasePlotter::initSettings() {
gridPrintingCurrentY=0; gridPrintingCurrentY=0;
internalPlotBorderLeft_notIncludingOutsidePlotSections=internalPlotBorderLeft=plotterStyle.plotBorderLeft; internalPlotBorderLeft_notIncludingAxisAndOutsidePlotSections=internalPlotBorderLeft_notIncludingOutsidePlotSections=internalPlotBorderLeft=plotterStyle.plotBorderLeft;
internalPlotBorderRight_notIncludingOutsidePlotSections=internalPlotBorderRight=plotterStyle.plotBorderRight; internalPlotBorderRight_notIncludingAxisAndOutsidePlotSections=internalPlotBorderRight_notIncludingOutsidePlotSections=internalPlotBorderRight=plotterStyle.plotBorderRight;
internalPlotBorderTop_notIncludingOutsidePlotSections=internalPlotBorderTop=plotterStyle.plotBorderTop; internalPlotBorderTop_notIncludingAxisAndOutsidePlotSections=internalPlotBorderTop_notIncludingOutsidePlotSections=internalPlotBorderTop=plotterStyle.plotBorderTop;
internalPlotBorderBottom_notIncludingOutsidePlotSections=internalPlotBorderBottom=plotterStyle.plotBorderBottom; internalPlotBorderBottom_notIncludingAxisAndOutsidePlotSections=internalPlotBorderBottom_notIncludingOutsidePlotSections=internalPlotBorderBottom=plotterStyle.plotBorderBottom;
//plotWidth=700; //plotWidth=700;
//plotHeight=150; //plotHeight=150;
@ -434,14 +437,18 @@ void JKQTBasePlotter::initSettings() {
void JKQTBasePlotter::zoomIn(double factor) { void JKQTBasePlotter::zoomIn(double factor) {
//std::cout<<(double)event->delta()/120.0<<": "<<factor<<std::endl; //std::cout<<(double)event->delta()/120.0<<": "<<factor<<std::endl;
double xmin=p2x(static_cast<long>(round(static_cast<double>(internalPlotWidth)/2.0-static_cast<double>(internalPlotWidth)/(2.0*factor))));
double xmax=p2x(static_cast<long>(round(static_cast<double>(internalPlotWidth)/2.0+static_cast<double>(internalPlotWidth)/(2.0*factor))));
double ymin=p2y(static_cast<long>(round(static_cast<double>(internalPlotHeight)/2.0+static_cast<double>(internalPlotHeight)/(2.0*factor))));
double ymax=p2y(static_cast<long>(round(static_cast<double>(internalPlotHeight)/2.0-static_cast<double>(internalPlotHeight)/(2.0*factor))));
for (auto ax: getXAxes(true)) {
const double xmin=ax->p2x(static_cast<long>(round(static_cast<double>(internalPlotWidth)/2.0-static_cast<double>(internalPlotWidth)/(2.0*factor))));
const double xmax=ax->p2x(static_cast<long>(round(static_cast<double>(internalPlotWidth)/2.0+static_cast<double>(internalPlotWidth)/(2.0*factor))));
ax->setRange(xmin, xmax);
}
for (auto ax: getYAxes(true)) {
const double ymin=ax->p2x(static_cast<long>(round(static_cast<double>(internalPlotHeight)/2.0+static_cast<double>(internalPlotHeight)/(2.0*factor))));
const double ymax=ax->p2x(static_cast<long>(round(static_cast<double>(internalPlotHeight)/2.0-static_cast<double>(internalPlotHeight)/(2.0*factor))));
ax->setRange(ymin, ymax);
}
xAxis->setRange(xmin, xmax);
yAxis->setRange(ymin, ymax);
if (emitPlotSignals) emit plotUpdated(); if (emitPlotSignals) emit plotUpdated();
if (emitSignals) emit zoomChangedLocally(xAxis->getMin(), xAxis->getMax(), yAxis->getMin(), yAxis->getMax(), this); if (emitSignals) emit zoomChangedLocally(xAxis->getMin(), xAxis->getMax(), yAxis->getMin(), yAxis->getMax(), this);
} }
@ -721,22 +728,36 @@ void JKQTBasePlotter::correctXYRangeForAspectRatio(double& xminn, double& xmaxx,
} }
void JKQTBasePlotter::setXY(double xminn, double xmaxx, double yminn, double ymaxx) { void JKQTBasePlotter::setXY(double xminn, double xmaxx, double yminn, double ymaxx, bool affectsSecondaryAxes) {
correctXYRangeForAspectRatio(xminn, xmaxx, yminn, ymaxx); correctXYRangeForAspectRatio(xminn, xmaxx, yminn, ymaxx);
const double xminpix=xAxis->x2p(xminn);
const double xmaxpix=xAxis->x2p(xmaxx);
const double yminpix=yAxis->x2p(yminn);
const double ymaxpix=yAxis->x2p(ymaxx);
xAxis->setRange(xminn, xmaxx); xAxis->setRange(xminn, xmaxx);
yAxis->setRange(yminn, ymaxx); yAxis->setRange(yminn, ymaxx);
if (affectsSecondaryAxes) {
for (auto ax: getXAxes(false)) {
ax->setRange(ax->p2x(xminpix), ax->p2x(xmaxpix));
}
for (auto ax: getYAxes(false)) {
ax->setRange(ax->p2x(yminpix), ax->p2x(ymaxpix));
}
}
if (emitSignals) emit zoomChangedLocally(xAxis->getMin(), xAxis->getMax(), yAxis->getMin(), yAxis->getMax(), this); if (emitSignals) emit zoomChangedLocally(xAxis->getMin(), xAxis->getMax(), yAxis->getMin(), yAxis->getMax(), this);
} }
void JKQTBasePlotter::setX(double xminn, double xmaxx){ void JKQTBasePlotter::setX(double xminn, double xmaxx, bool affectsSecondaryAxes){
setXY(xminn, xmaxx, yAxis->getMin(), yAxis->getMax()); setXY(xminn, xmaxx, yAxis->getMin(), yAxis->getMax(), affectsSecondaryAxes);
} }
void JKQTBasePlotter::setY(double yminn, double ymaxx) { void JKQTBasePlotter::setY(double yminn, double ymaxx, bool affectsSecondaryAxes) {
setXY(xAxis->getMin(), xAxis->getMax(), yminn, ymaxx); setXY(xAxis->getMin(), xAxis->getMax(), yminn, ymaxx, affectsSecondaryAxes);
} }
void JKQTBasePlotter::setAbsoluteX(double xminn, double xmaxx) { void JKQTBasePlotter::setAbsoluteX(double xminn, double xmaxx) {
@ -820,7 +841,7 @@ void JKQTBasePlotter::calcPlotScaling(JKQTPEnhancedPainter& painter){
/*if (displayMousePosition) { /*if (displayMousePosition) {
QFontMetrics fm=fontMetrics(); QFontMetrics fm=fontMetrics();
QString test="<EFBFBD>Aquator"; QString test="Aquator";
int labelHeight=fm.size(Qt::TextSingleLine, test).height()*1.5; int labelHeight=fm.size(Qt::TextSingleLine, test).height()*1.5;
//if (mousePosLabel!=nullptr) labelHeight=mousePosLabel->height(); //if (mousePosLabel!=nullptr) labelHeight=mousePosLabel->height();
internalPlotBorderTop=internalPlotBorderTop+(labelHeight-plotBorderTop)*1.1; internalPlotBorderTop=internalPlotBorderTop+(labelHeight-plotBorderTop)*1.1;
@ -837,15 +858,27 @@ void JKQTBasePlotter::calcPlotScaling(JKQTPEnhancedPainter& painter){
s=yAxis->getSize2(painter); s=yAxis->getSize2(painter);
internalPlotBorderRight+=s.width(); internalPlotBorderRight+=s.width();
internalPlotBorderTop_notIncludingAxisAndOutsidePlotSections=internalPlotBorderTop;
internalPlotBorderLeft_notIncludingAxisAndOutsidePlotSections=internalPlotBorderLeft;
internalPlotBorderBottom_notIncludingAxisAndOutsidePlotSections=internalPlotBorderBottom;
internalPlotBorderRight_notIncludingAxisAndOutsidePlotSections=internalPlotBorderRight;
// read size required by secondary axes
for (const auto& ax: qAsConst(secondaryYAxis)) {
internalPlotBorderLeft+=ax->getSize1(painter).width()+plotterStyle.secondaryAxisSeparation;
internalPlotBorderRight+=ax->getSize2(painter).width()+plotterStyle.secondaryAxisSeparation;
}
for (const auto& ax: qAsConst(secondaryXAxis)) {
internalPlotBorderBottom+=ax->getSize1(painter).height()+plotterStyle.secondaryAxisSeparation;
internalPlotBorderTop+=ax->getSize2(painter).height()+plotterStyle.secondaryAxisSeparation;
}
internalPlotBorderTop_notIncludingOutsidePlotSections=internalPlotBorderTop; internalPlotBorderTop_notIncludingOutsidePlotSections=internalPlotBorderTop;
internalPlotBorderLeft_notIncludingOutsidePlotSections=internalPlotBorderLeft; internalPlotBorderLeft_notIncludingOutsidePlotSections=internalPlotBorderLeft;
internalPlotBorderBottom_notIncludingOutsidePlotSections=internalPlotBorderBottom; internalPlotBorderBottom_notIncludingOutsidePlotSections=internalPlotBorderBottom;
internalPlotBorderRight_notIncludingOutsidePlotSections=internalPlotBorderRight; internalPlotBorderRight_notIncludingOutsidePlotSections=internalPlotBorderRight;
// read additional space required by graphs // read additional space required by graphs
for (int i=0; i<graphs.size(); i++) { for (int i=0; i<graphs.size(); i++) {
if (graphs[i]->isVisible()) { if (graphs[i]->isVisible()) {
@ -925,8 +958,9 @@ void JKQTBasePlotter::calcPlotScaling(JKQTPEnhancedPainter& painter){
} }
xAxis->calcPlotScaling(true); for (auto ax: getAxes(true)) {
yAxis->calcPlotScaling(true); ax->calcPlotScaling(true);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// ENSURE ASPECT RATIO OF PLOT 1x1 PIXELS (if activated) // ENSURE ASPECT RATIO OF PLOT 1x1 PIXELS (if activated)
@ -948,8 +982,9 @@ void JKQTBasePlotter::calcPlotScaling(JKQTPEnhancedPainter& painter){
} }
xAxis->setRange(xmid-newPlotWidth/2.0, xmid+newPlotWidth/2.0); xAxis->setRange(xmid-newPlotWidth/2.0, xmid+newPlotWidth/2.0);
yAxis->setRange(ymid-newPlotHeight/2.0, ymid+newPlotHeight/2.0); yAxis->setRange(ymid-newPlotHeight/2.0, ymid+newPlotHeight/2.0);
xAxis->calcPlotScaling(true); for (auto ax: getAxes(true)) {
yAxis->calcPlotScaling(true); ax->calcPlotScaling(true);
}
} }
@ -963,8 +998,10 @@ void JKQTBasePlotter::drawSystemGrid(JKQTPEnhancedPainter& painter) {
JKQTPAutoOutputTimer jkaaot("JKQTBasePlotter::drawSystemGrid"); JKQTPAutoOutputTimer jkaaot("JKQTBasePlotter::drawSystemGrid");
#endif #endif
//qDebug()<<"start JKQTBasePlotter::drawSystemGrid"; //qDebug()<<"start JKQTBasePlotter::drawSystemGrid";
xAxis->drawGrids(painter); for (auto ax: getAxes(true)) {
yAxis->drawGrids(painter); ax->drawGrids(painter);
}
//qDebug()<<" end JKQTBasePlotter::drawSystemGrid"; //qDebug()<<" end JKQTBasePlotter::drawSystemGrid";
} }
@ -972,9 +1009,24 @@ void JKQTBasePlotter::drawSystemXAxis(JKQTPEnhancedPainter& painter) {
#ifdef JKQTBP_AUTOTIMER #ifdef JKQTBP_AUTOTIMER
JKQTPAutoOutputTimer jkaaot("JKQTBasePlotter::drawSystemXAxis"); JKQTPAutoOutputTimer jkaaot("JKQTBasePlotter::drawSystemXAxis");
#endif #endif
//qDebug()<<"start JKQTBasePlotter::drawSystemXAxis"; //qDebug()<<"start JKQTBasePlotter::drawSystemXAxis";
xAxis->drawAxes(painter); xAxis->drawAxes(painter);
//qDebug()<<" end JKQTBasePlotter::drawSystemXAxis"; //qDebug()<<" end JKQTBasePlotter::drawSystemXAxis";
if (secondaryXAxis.size()>0) {
double ibMove1=xAxis->getSize1(painter).height();
if (ibMove1>0) ibMove1+=plotterStyle.secondaryAxisSeparation;
double ibMove2=xAxis->getSize2(painter).height();
if (ibMove2>0) ibMove1+=plotterStyle.secondaryAxisSeparation;
for (auto& ax: secondaryXAxis) {
ax->drawAxes(painter, ibMove1, ibMove2);
const double add1=ax->getSize1(painter).height();
const double add2=ax->getSize2(painter).height();
if (add1>0) ibMove1+=add1+plotterStyle.secondaryAxisSeparation;
if (add2>0) ibMove2+=add2+plotterStyle.secondaryAxisSeparation;
}
}
} }
void JKQTBasePlotter::drawSystemYAxis(JKQTPEnhancedPainter& painter) { void JKQTBasePlotter::drawSystemYAxis(JKQTPEnhancedPainter& painter) {
@ -984,6 +1036,21 @@ void JKQTBasePlotter::drawSystemYAxis(JKQTPEnhancedPainter& painter) {
//qDebug()<<"start JKQTBasePlotter::drawSystemYAxis"; //qDebug()<<"start JKQTBasePlotter::drawSystemYAxis";
yAxis->drawAxes(painter); yAxis->drawAxes(painter);
//qDebug()<<" end JKQTBasePlotter::drawSystemYAxis"; //qDebug()<<" end JKQTBasePlotter::drawSystemYAxis";
if (secondaryYAxis.size()>0) {
double ibMove1=yAxis->getSize1(painter).width();
if (ibMove1>0) ibMove1+=plotterStyle.secondaryAxisSeparation;
double ibMove2=yAxis->getSize2(painter).width();
if (ibMove2>0) ibMove1+=plotterStyle.secondaryAxisSeparation;
for (auto& ax: secondaryYAxis) {
ax->drawAxes(painter, ibMove1, ibMove2);
const double add1=ax->getSize1(painter).width();
const double add2=ax->getSize2(painter).width();
if (add1>0) ibMove1+=add1+plotterStyle.secondaryAxisSeparation;
if (add2>0) ibMove2+=add2+plotterStyle.secondaryAxisSeparation;
}
}
} }
@ -1332,6 +1399,12 @@ void JKQTBasePlotter::drawPlot(JKQTPEnhancedPainter& painter) {
p.setStyle(Qt::DotLine); p.setStyle(Qt::DotLine);
painter.setPen(p); painter.setPen(p);
painter.drawRect(QRectF(internalPlotBorderLeft_notIncludingOutsidePlotSections, internalPlotBorderTop_notIncludingOutsidePlotSections, widgetWidth-internalPlotBorderLeft_notIncludingOutsidePlotSections-internalPlotBorderRight_notIncludingOutsidePlotSections, widgetHeight-internalPlotBorderTop_notIncludingOutsidePlotSections-internalPlotBorderBottom_notIncludingOutsidePlotSections)); painter.drawRect(QRectF(internalPlotBorderLeft_notIncludingOutsidePlotSections, internalPlotBorderTop_notIncludingOutsidePlotSections, widgetWidth-internalPlotBorderLeft_notIncludingOutsidePlotSections-internalPlotBorderRight_notIncludingOutsidePlotSections, widgetHeight-internalPlotBorderTop_notIncludingOutsidePlotSections-internalPlotBorderBottom_notIncludingOutsidePlotSections));
p.setColor(QColor("goldenrod"));
col=p.color(); col.setAlphaF(0.8f); p.setColor(col);
p.setWidthF(plotterStyle.debugRegionLineWidth);
p.setStyle(Qt::DotLine);
painter.setPen(p);
painter.drawRect(QRectF(internalPlotBorderLeft_notIncludingAxisAndOutsidePlotSections, internalPlotBorderTop_notIncludingAxisAndOutsidePlotSections, widgetWidth-internalPlotBorderLeft_notIncludingAxisAndOutsidePlotSections-internalPlotBorderRight_notIncludingAxisAndOutsidePlotSections, widgetHeight-internalPlotBorderTop_notIncludingAxisAndOutsidePlotSections-internalPlotBorderBottom_notIncludingAxisAndOutsidePlotSections));
p.setColor(QColor("yellow")); p.setColor(QColor("yellow"));
col=p.color(); col.setAlphaF(0.8f); p.setColor(col); col=p.color(); col.setAlphaF(0.8f); p.setColor(col);
p.setWidthF(plotterStyle.debugRegionLineWidth); p.setWidthF(plotterStyle.debugRegionLineWidth);
@ -2439,6 +2512,11 @@ void JKQTBasePlotter::drawNonGrid(JKQTPEnhancedPainter& painter, const QPoint& p
emitPlotSignals=oldEmitPlotSignals; emitPlotSignals=oldEmitPlotSignals;
} }
void JKQTBasePlotter::updateSecondaryAxes()
{
}
void JKQTBasePlotter::setEmittingPlotSignalsEnabled(bool __value) void JKQTBasePlotter::setEmittingPlotSignalsEnabled(bool __value)
{ {
this->emitPlotSignals = __value; this->emitPlotSignals = __value;
@ -3227,20 +3305,95 @@ const JKQTMathText *JKQTBasePlotter::getMathText() const {
return &mathText; return &mathText;
} }
JKQTPHorizontalAxis *JKQTBasePlotter::getXAxis() { JKQTPHorizontalAxisBase *JKQTBasePlotter::getXAxis(JKQTPCoordinateAxisRef axis) {
return xAxis; if (axis==JKQTPPrimaryAxis) return xAxis;
else return secondaryXAxis[axis];
} }
JKQTPVerticalAxis *JKQTBasePlotter::getYAxis() { JKQTPVerticalAxisBase *JKQTBasePlotter::getYAxis(JKQTPCoordinateAxisRef axis) {
return yAxis; if (axis==JKQTPPrimaryAxis) return yAxis;
else return secondaryYAxis[axis];
} }
const JKQTPHorizontalAxis *JKQTBasePlotter::getXAxis() const { const JKQTPHorizontalAxisBase *JKQTBasePlotter::getXAxis(JKQTPCoordinateAxisRef axis) const {
return xAxis; if (axis==JKQTPPrimaryAxis) return xAxis;
else return secondaryXAxis[axis];
} }
const JKQTPVerticalAxis *JKQTBasePlotter::getYAxis() const { const JKQTPVerticalAxisBase *JKQTBasePlotter::getYAxis(JKQTPCoordinateAxisRef axis) const {
return yAxis; if (axis==JKQTPPrimaryAxis) return yAxis;
else return secondaryYAxis[axis];
}
bool JKQTBasePlotter::hasXAxis(JKQTPCoordinateAxisRef axis) const
{
return secondaryXAxis.contains(axis);
}
bool JKQTBasePlotter::hasYAxis(JKQTPCoordinateAxisRef axis) const
{
return secondaryYAxis.contains(axis);
}
QSet<JKQTPCoordinateAxisRef> JKQTBasePlotter::getAvailableXAxisRefs(bool includePrimary) const
{
QSet<JKQTPCoordinateAxisRef> res(secondaryXAxis.keyBegin(),secondaryXAxis.keyEnd());
if (includePrimary) res.insert(JKQTPPrimaryAxis);
return res;
}
QSet<JKQTPCoordinateAxisRef> JKQTBasePlotter::getAvailableYAxisRefs(bool includePrimary) const
{
QSet<JKQTPCoordinateAxisRef> res(secondaryYAxis.keyBegin(),secondaryYAxis.keyEnd());
if (includePrimary) res.insert(JKQTPPrimaryAxis);
return res;
}
QMap<JKQTPCoordinateAxisRef, JKQTPHorizontalAxisBase *> JKQTBasePlotter::getXAxes(bool includePrimary)
{
QMap<JKQTPCoordinateAxisRef, JKQTPHorizontalAxisBase *> res=secondaryXAxis;
if (includePrimary) res[JKQTPPrimaryAxis]=xAxis;
return res;
}
QMap<JKQTPCoordinateAxisRef, JKQTPVerticalAxisBase *> JKQTBasePlotter::getYAxes(bool includePrimary)
{
QMap<JKQTPCoordinateAxisRef, JKQTPVerticalAxisBase *> res=secondaryYAxis;
if (includePrimary) res[JKQTPPrimaryAxis]=yAxis;
return res;
}
QList<JKQTPCoordinateAxis *> JKQTBasePlotter::getAxes(bool includePrimaries)
{
QList<JKQTPCoordinateAxis *> res;
if (includePrimaries) res<<xAxis<<yAxis;
for (auto& ax: secondaryXAxis) res<<ax;
for (auto& ax: secondaryYAxis) res<<ax;
return res;
}
JKQTPCoordinateAxisRef JKQTBasePlotter::addSecondaryXAxis(JKQTPHorizontalAxisBase *axis)
{
const auto keys=secondaryXAxis.keys();
JKQTPCoordinateAxisRef ref=JKQTPSecondaryAxis;
if (keys.size()>0) {
ref=static_cast<JKQTPCoordinateAxisRef>(static_cast<int>(*std::max_element(keys.begin(), keys.end()))+1);
}
secondaryXAxis[ref]=axis;
axis->setParent(this);
return ref;
}
JKQTPCoordinateAxisRef JKQTBasePlotter::addSecondaryYAxis(JKQTPVerticalAxisBase *axis)
{
const auto keys=secondaryYAxis.keys();
JKQTPCoordinateAxisRef ref=JKQTPSecondaryAxis;
if (keys.size()>0) {
ref=static_cast<JKQTPCoordinateAxisRef>(static_cast<int>(*std::max_element(keys.begin(), keys.end()))+1);
}
secondaryYAxis[ref]=axis;
axis->setParent(this);
return ref;
} }
QAction *JKQTBasePlotter::getActionSavePlot() const { QAction *JKQTBasePlotter::getActionSavePlot() const {
@ -4565,13 +4718,14 @@ void JKQTBasePlotter::saveUserSettings() const
void JKQTBasePlotter::getGraphsXMinMax(double& minx, double& maxx, double& smallestGreaterZero) { bool JKQTBasePlotter::getGraphsXMinMax(double& minx, double& maxx, double& smallestGreaterZero, const PlotElementPreciate& predicate) {
bool start=true; bool start=true;
minx=0; minx=0;
maxx=0; maxx=0;
smallestGreaterZero=0; smallestGreaterZero=0;
size_t count=0;
for (int i=0; i<graphs.size(); i++) { for (int i=0; i<graphs.size(); i++) {
if (graphs[i]->isVisible()) { if (graphs[i]->isVisible() && predicate(graphs[i])) {
double gminx=0; double gminx=0;
double gmaxx=0; double gmaxx=0;
@ -4589,6 +4743,7 @@ void JKQTBasePlotter::getGraphsXMinMax(double& minx, double& maxx, double& small
//std::cout<<" "<<i<<": gminx="<<gminx<<" gmaxx="<<gmaxx<<" minx="<<minx<<" maxx="<<maxx<<std::endl; //std::cout<<" "<<i<<": gminx="<<gminx<<" gmaxx="<<gmaxx<<" minx="<<minx<<" maxx="<<maxx<<std::endl;
start=false; start=false;
count++;
} else { } else {
//std::cout<<" -> "<<i<<": "<<graphs[i]->getTitle().toStdString()<<": FALSE"<<std::endl; //std::cout<<" -> "<<i<<": "<<graphs[i]->getTitle().toStdString()<<": FALSE"<<std::endl;
} }
@ -4596,15 +4751,17 @@ void JKQTBasePlotter::getGraphsXMinMax(double& minx, double& maxx, double& small
//std::cout<<" -> "<<i<<": "<<graphs[i]->getTitle().toStdString()<<": INVISIBLE"<<std::endl; //std::cout<<" -> "<<i<<": "<<graphs[i]->getTitle().toStdString()<<": INVISIBLE"<<std::endl;
} }
} }
return count>0;
} }
void JKQTBasePlotter::getGraphsYMinMax(double& miny, double& maxy, double& smallestGreaterZero) { bool JKQTBasePlotter::getGraphsYMinMax(double& miny, double& maxy, double& smallestGreaterZero, const PlotElementPreciate &predicate) {
bool start=true; bool start=true;
miny=0; miny=0;
maxy=0; maxy=0;
smallestGreaterZero=0; smallestGreaterZero=0;
size_t count=0;
for (int i=0; i<graphs.size(); i++) { for (int i=0; i<graphs.size(); i++) {
if (graphs[i]->isVisible()) { if (graphs[i]->isVisible() && predicate(graphs[i])) {
double gminy=0; double gminy=0;
double gmaxy=0; double gmaxy=0;
double gsmallestGreaterZero=0; double gsmallestGreaterZero=0;
@ -4618,105 +4775,82 @@ void JKQTBasePlotter::getGraphsYMinMax(double& miny, double& maxy, double& small
xvsgz=gminy; if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz; xvsgz=gminy; if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
start=false; start=false;
count++;
} }
} }
} }
return count>0;
} }
void JKQTBasePlotter::zoomToFit(bool zoomX, bool zoomY, bool includeX0, bool includeY0, double scaleX, double scaleY) { void JKQTBasePlotter::zoomToFit(bool zoomX, bool zoomY, bool includeX0, bool includeY0, double scaleX, double scaleY) {
// std::cout<<"JKQTBasePlotter::zoomToFit():\n"; // std::cout<<"JKQTBasePlotter::zoomToFit():\n";
if (graphs.size()<=0) return; if (graphs.size()<=0) return;
if (zoomX) { auto calcLocScaling=[](JKQTPCoordinateAxis* axis, double &xxmin, double&xxmax, double&xsmallestGreaterZero, bool include0, double scale) -> bool {
double xxmin=0;
double xxmax=0;
double xsmallestGreaterZero=0;
getGraphsXMinMax(xxmin, xxmax, xsmallestGreaterZero);
//std::cout<<" xxmin="<<xxmin<<" xxmax="<<xxmax<<std::endl;
if (JKQTPIsOKFloat(xxmin) && JKQTPIsOKFloat(xxmax)) { if (JKQTPIsOKFloat(xxmin) && JKQTPIsOKFloat(xxmax)) {
bool doScale=true; bool doScale=true;
if (fabs(xxmin-xxmax)<1e-305) { if (fabs(xxmin-xxmax)<1e-305) {
xxmin=xAxis->getMin(); xxmin=axis->getMin();
xxmax=xAxis->getMax(); xxmax=axis->getMax();
doScale=false; doScale=false;
} }
if (xAxis->isLogAxis()) { if (axis->isLogAxis()) {
if ((xxmin<=1e-305)&&(xxmax<=1e-305)) {xxmin=0.1; xxmax=1.0; } if ((xxmin<=1e-305)&&(xxmax<=1e-305)) {xxmin=0.1; xxmax=1.0; }
else if ((xxmin<=1e-305)&&(xxmax>0)) { else if ((xxmin<=1e-305)&&(xxmax>0)) {
if (xsmallestGreaterZero>10.0*DBL_MIN) xxmin=xsmallestGreaterZero; if (xsmallestGreaterZero>10.0*DBL_MIN) xxmin=xsmallestGreaterZero;
else xxmin=xxmax/xAxis->getLogAxisBase(); else xxmin=xxmax/axis->getLogAxisBase();
} }
if (doScale) { if (doScale) {
double d=scaleX*(log(xxmax)-log(xxmin)); // new width double d=scale*(log(xxmax)-log(xxmin)); // new width
double c=(log(xxmax)+log(xxmin))/2.0; // center of interval double c=(log(xxmax)+log(xxmin))/2.0; // center of interval
xxmin=exp(c-d/2.0); xxmin=exp(c-d/2.0);
xxmax=exp(c+d/2.0); xxmax=exp(c+d/2.0);
} }
} else if (doScale) { } else if (doScale) {
double d=scaleX*(xxmax-xxmin); // new width double d=scale*(xxmax-xxmin); // new width
double c=(xxmax+xxmin)/2.0; // center of interval double c=(xxmax+xxmin)/2.0; // center of interval
xxmin=c-d/2.0; xxmin=c-d/2.0;
xxmax=c+d/2.0; xxmax=c+d/2.0;
} }
if (includeX0 && !xAxis->isLogAxis()) { if (include0 && !axis->isLogAxis()) {
if (xxmin>0) xxmin=0; if (xxmin>0) xxmin=0;
else if (xxmax<0) xxmax=0; else if (xxmax<0) xxmax=0;
} }
//std::cout<<" => xxmin="<<xxmin<<" xxmax="<<xxmax<<std::endl;
if (JKQTPIsOKFloat(xxmin) && JKQTPIsOKFloat(xxmax)) { if (JKQTPIsOKFloat(xxmin) && JKQTPIsOKFloat(xxmax)) {
setX(xxmin, xxmax); axis->setRange(xxmin, xxmax);
} else if (!JKQTPIsOKFloat(xxmin) && JKQTPIsOKFloat(xxmax)) { } else if (!JKQTPIsOKFloat(xxmin) && JKQTPIsOKFloat(xxmax)) {
setX(getXMin(), xxmax); axis->setRange(axis->getMin(), xxmax);
} else if (JKQTPIsOKFloat(xxmin) && !JKQTPIsOKFloat(xxmax)) { } else if (JKQTPIsOKFloat(xxmin) && !JKQTPIsOKFloat(xxmax)) {
setX(xxmin, getXMax()); axis->setRange(xxmin, axis->getMax());
}
return doScale;
}
return false;
};
if (zoomX) {
const auto axes=getXAxes();
for (auto it=axes.begin(); it!=axes.end(); ++it) {
double xxmin=0;
double xxmax=0;
double xsmallestGreaterZero=0;
if (getGraphsXMinMax(xxmin, xxmax, xsmallestGreaterZero, filterPlotElementByXAxis(it.key()))) {
calcLocScaling(it.value(), xxmin, xxmax, xsmallestGreaterZero, includeX0, scaleX);
} }
} }
} }
if (zoomY) { if (zoomY) {
double yymin=0; const auto axes=getYAxes();
double yymax=0; for (auto it=axes.begin(); it!=axes.end(); ++it) {
double ysmallestGreaterZero=0; double xxmin=0;
getGraphsYMinMax(yymin, yymax, ysmallestGreaterZero); double xxmax=0;
//std::cout<<" yymin="<<yymin<<" yymax="<<yymax<<std::endl; double xsmallestGreaterZero=0;
bool doScale=true; if (getGraphsYMinMax(xxmin, xxmax, xsmallestGreaterZero, filterPlotElementByYAxis(it.key()))) {
if (fabs(yymin-yymax)<1e-305) { calcLocScaling(it.value(), xxmin, xxmax, xsmallestGreaterZero, includeY0, scaleY);
yymin=yAxis->getMin();
yymax=yAxis->getMax();
doScale=false;
}
if (yAxis->getLogAxis()) {
if ((yymin<=1e-305)&&(yymax<=1e-305)) {yymin=0.1; yymax=1.0; }
else if ((yymin<=1e-305)&&(yymax>0)) {
if (ysmallestGreaterZero>10.0*DBL_MIN) yymin=ysmallestGreaterZero;
else yymin=yymax/yAxis->getLogAxisBase();
} }
if (doScale) {
double d=scaleY*(log(yymax)-log(yymin)); // new width
double c=(log(yymax)+log(yymin))/2.0; // center of interval
yymin=exp(c-d/2.0);
yymax=exp(c+d/2.0);
}
} else if (doScale) {
double d=scaleY*(yymax-yymin); // new width
double c=(yymax+yymin)/2.0; // center of interval
yymin=c-d/2.0;
yymax=c+d/2.0;
} }
if (includeY0 && !yAxis->getLogAxis()) {
if (yymin>0) yymin=0;
else if (yymax<0) yymax=0;
}
//std::cout<<" => yymin="<<yymin<<" yymax="<<yymax<<std::endl;
if (JKQTPIsOKFloat(yymin) && JKQTPIsOKFloat(yymax)) {
setY(yymin, yymax);
} else if (!JKQTPIsOKFloat(yymin) && JKQTPIsOKFloat(yymax)) {
setY(getYMin(), yymax);
} else if (JKQTPIsOKFloat(yymin) && !JKQTPIsOKFloat(yymax)) {
setY(yymin, getYMax());
}
} }
//std::cout<<"end of zoomToFit\n"; //std::cout<<"end of zoomToFit\n";
//setXY(xxmin, xxmax, yymin, yymax); //setXY(xxmin, xxmax, yymin, yymax);
@ -5075,8 +5209,9 @@ void JKQTBasePlotter::showPlotData() {
void JKQTBasePlotter::setEmittingSignalsEnabled(bool enabled) void JKQTBasePlotter::setEmittingSignalsEnabled(bool enabled)
{ {
emitSignals=enabled; emitSignals=enabled;
xAxis->setDoUpdateScaling(enabled); for (auto ax: getAxes(true)) {
yAxis->setDoUpdateScaling(enabled); ax->setDoUpdateScaling(enabled);
}
} }
@ -5295,3 +5430,7 @@ void JKQTBasePlotter::JKQTPPen::setSymbolType(JKQTPGraphSymbols symbol)
{ {
m_symbol=symbol; m_symbol=symbol;
} }
bool JKQTBasePlotter::filterPlotElementByXAxis::operator()(const JKQTPPlotElement *el) const { return el->getXAxisRef()==ref; }
bool JKQTBasePlotter::filterPlotElementByYAxis::operator()(const JKQTPPlotElement *el) const { return el->getYAxisRef()==ref; }

View File

@ -93,6 +93,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPPaintDeviceAdapter {
virtual QPaintDevice* createPaintdeviceMM(const QString& filename, double widthMM, double heightMM) const; virtual QPaintDevice* createPaintdeviceMM(const QString& filename, double widthMM, double heightMM) const;
}; };
/** \brief base class for 2D plotter classes (used by the plotter widget JKQTPlotter) /** \brief base class for 2D plotter classes (used by the plotter widget JKQTPlotter)
* \ingroup jkqtpplotterclasses * \ingroup jkqtpplotterclasses
* *
@ -137,12 +138,49 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPPaintDeviceAdapter {
* *
* *
* \section jkqtplotter_base_grids_baseplotter Axis Ticks and Grids * \section jkqtplotter_base_grids_baseplotter Axis Ticks and Grids
* - The plotting of coordinate axes and grids, as well as coordinate transforms is done by *
* JKQTPCoordinateAxis descendents (see documentation there) * \subsection jkqtplotter_base_grids_baseplotter_majoraxes Major Coordinate Axes
* . *
* JKQTBasePlotter - by default - has two major axes: A horizontal x-axis and a vertical y-axis.
*
* The plotting of coordinate axes and grids, as well as coordinate transforms is done by
* JKQTPCoordinateAxis descendents (see documentation there).
*
* If you want to set the axis properties, use getXAxis() or getYAxis() to get a pointer to the axis objects which then * If you want to set the axis properties, use getXAxis() or getYAxis() to get a pointer to the axis objects which then
* may be used to set the axis properties. * may be used to set the axis properties.
* *
* \subsection jkqtplotter_base_grids_baseplotter_secondaryaxes Secondary Coordinate Axes
*
* In addition a plot may contain secondary axes, as shown below:
*
* \image html JKQTBasePlotter_addSecondaryYAxis.png
*
* You can add additional x-axes using addSecondaryXAxis() and y-axes using addSecondaryYAxis().
* These functions return a JKQTPCoordinateAxisRef, which can be used to reference these axes, when
* calling function like getXAxis() here the default-parameter call getXAxis(JKQTPPrimaryAxis) returns
* the primary axis (JKQTPPrimaryAxis may be omitted) and calling getXAxis(JKQTPSecondaryAxis) will return
* the first secondary axis and so on.
*
* In graphs (derived from JKQTPPlotElement) you can use JKQTPPlotElement::setXAxis() and JKQTPPlotElement::setYAxis()
* with a JKQTPCoordinateAxisRef as parameter to tell plots to use another axis.
*
* Using a JKQTPCoordinateAxisRef instead of a pointer to a JKQTPCoordinateAxis allows to exchange the axes in the plot,
* while not breaking the graphs.
*
* Here is a code example of how to use secondary axes:
* \code
* // construct a new x-axis-object
* JKQTPHorizontalAxisBase* secXAxis=new JKQTPHorizontalAxis(plot.getPlotter(), JKQTPPrimaryAxis)
* // add it to the plot
* auto xAxisRef2=plot.getPlotter()->addSecondaryXAxis(secXAxis);
* // ... now you can access it:
* plot.getXAxis(xAxisRef2)->setShowZeroAxis(false);
* // ... and use it for graphs:
* graph2->setXAxis(xAxisRef2);
* \endcode
*
* \see addSecondaryXAxis(), addSecondaryYAxis(), getXAxis(), getYAxis()
*
* *
* \section jkqtbaseplotter_appearance_and_style Appearance & Styling of the Graph * \section jkqtbaseplotter_appearance_and_style Appearance & Styling of the Graph
* *
@ -656,6 +694,13 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
*/ */
void drawNonGrid(JKQTPEnhancedPainter& painter, const QPoint& pos=QPoint(0,0)); void drawNonGrid(JKQTPEnhancedPainter& painter, const QPoint& pos=QPoint(0,0));
/** \brief updates the secondary axes
*
* The plot may contain (in addition to its primary axes) also secondary axes, that depend in their
* scaling (min,max, ...) on the primmary axes of the plot. This function updates/recalculates the
* scaling of these axes.
*/
void updateSecondaryAxes();
/** \brief emit plotUpdated() */ /** \brief emit plotUpdated() */
void redrawPlot() { if (emitPlotSignals) emit plotUpdated(); } void redrawPlot() { if (emitPlotSignals) emit plotUpdated(); }
@ -826,17 +871,98 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
JKQTMathText* getMathText(); JKQTMathText* getMathText();
/** \brief returns the internal JKQTMathText, used to render text with LaTeX markup */ /** \brief returns the internal JKQTMathText, used to render text with LaTeX markup */
const JKQTMathText *getMathText() const; const JKQTMathText *getMathText() const;
/** \brief returns the x-axis objet of the plot */ /** \brief returns the x-axis objet of the plot
JKQTPHorizontalAxis *getXAxis(); *
/** \brief returns the y-axis objet of the plot */ * \see \ref jkqtplotter_base_grids_baseplotter
JKQTPVerticalAxis* getYAxis(); */
/** \brief returns the x-axis objet of the plot */ JKQTPHorizontalAxisBase *getXAxis(JKQTPCoordinateAxisRef axis=JKQTPPrimaryAxis);
const JKQTPHorizontalAxis* getXAxis() const; /** \brief returns the y-axis objet of the plot
/** \brief returns the y-axis objet of the plot */ *
const JKQTPVerticalAxis *getYAxis() const; * \see \ref jkqtplotter_base_grids_baseplotter
*/
JKQTPVerticalAxisBase* getYAxis(JKQTPCoordinateAxisRef axis=JKQTPPrimaryAxis);
/** \brief returns the x-axis objet of the plot
*
* \see \ref jkqtplotter_base_grids_baseplotter
*/
const JKQTPHorizontalAxisBase* getXAxis(JKQTPCoordinateAxisRef axis=JKQTPPrimaryAxis) const;
/** \brief returns the y-axis objet of the plot
*
* \see \ref jkqtplotter_base_grids_baseplotter
*/
const JKQTPVerticalAxisBase *getYAxis(JKQTPCoordinateAxisRef axis=JKQTPPrimaryAxis) const;
/** \brief returns whether an x-axis \a axis is registered with the plotter
*
* \note For \a axis \c ==JKQTPPrimaryAxis this function returns always \c true
*/
bool hasXAxis(JKQTPCoordinateAxisRef axis=JKQTPPrimaryAxis) const;
/** \brief returns whether a y-axis \a axis is registered with the plotter
*
* \note For \a axis \c ==JKQTPPrimaryAxis this function returns always \c true
*/
bool hasYAxis(JKQTPCoordinateAxisRef axis=JKQTPPrimaryAxis) const;
/** \brief returns the set of available x-axes (including the primary, if \c true is given as parameter) */
QSet<JKQTPCoordinateAxisRef> getAvailableXAxisRefs(bool includePrimary=false) const;
/** \brief returns the set of available y-axes (including the primary, if \c true is given as parameter) */
QSet<JKQTPCoordinateAxisRef> getAvailableYAxisRefs(bool includePrimary=false) const;
/** \brief returns all available x-axes */
QMap<JKQTPCoordinateAxisRef, JKQTPHorizontalAxisBase*> getXAxes(bool includePrimary=true);
/** \brief returns all available y-axes */
QMap<JKQTPCoordinateAxisRef, JKQTPVerticalAxisBase*> getYAxes(bool includePrimary=true);
/** \brief returns all available x- or y-axes */
QList<JKQTPCoordinateAxis*> getAxes(bool includePrimaries=true);
/** \brief adds a secondary x-axis
*
* \params axis the JKQTPHorizontalAxisBase object to add
* \returns a reference to this axis
*
* Usage is simple:
* \code
* // construct a new x-axis-object
* JKQTPHorizontalAxisBase* secXAxis=new JKQTPHorizontalAxis(plot.getPlotter(), JKQTPPrimaryAxis)
* // add it to the plot
* auto xAxisRef2=plot.getPlotter()->addSecondaryXAxis(secXAxis);
* // ... now you can access it:
* plot.getXAxis(xAxisRef2)->setShowZeroAxis(false);
* // ... and use it for graphs:
* graph2->setXAxis(xAxisRef2);
* \endcode
*
*
* Here is an example output:
*
* \image html JKQTBasePlotter_addSecondaryXAxis.png
*
* \see \ref jkqtplotter_base_grids_baseplotter_secondaryaxes , \subpage JKQTPlotterSecondaryAxes
*/
JKQTPCoordinateAxisRef addSecondaryXAxis(JKQTPHorizontalAxisBase* axis);
/** \brief adds a secondary y-axis
*
* \params axis the JKQTPVerticalAxisBase object to add
* \returns a reference to this axis
*
* Usage is simple:
* \code
* // construct a new y-axis-object
* JKQTPVerticalAxisBase* secYAxis=new JKQTPVerticalAxis(plot.getPlotter(), JKQTPPrimaryAxis)
* // add it to the plot
* auto yAxisRef2=plot.getPlotter()->addSecondaryYAxis(secYAxis);
* // ... now you can access it:
* plot.getYAxis(yAxisRef2)->setShowZeroAxis(false);
* // ... and use it for graphs:
* graph2->setYAxis(yAxisRef2);
* \endcode
*
* Here is an example output:
*
* \image html JKQTBasePlotter_addSecondaryYAxis.png
*
* \see \ref jkqtplotter_base_grids_baseplotter_secondaryaxes , \subpage JKQTPlotterSecondaryAxes
*/
JKQTPCoordinateAxisRef addSecondaryYAxis(JKQTPVerticalAxisBase* axis);
/** \copydoc actSavePlot */ /** \copydoc actSavePlot */
QAction* getActionSavePlot() const; QAction* getActionSavePlot() const;
/** \copydoc actSaveData */ /** \copydoc actSaveData */
QAction* getActionSaveData() const; QAction* getActionSaveData() const;
@ -953,22 +1079,62 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
} }
} }
/** \brief Functor which can be used as filter predicate for getGraphsXMinMax() or getGraphsYMinMax()
*
* \see getGraphsXMinMax(), getGraphsYMinMax(), allPlotElements
*/
typedef std::function<bool(const JKQTPPlotElement*)> PlotElementPreciate;
/** \brief Functor which does not apply any filter to JKQTPPlotElement, e.g. in getGraphsXMinMax() or getGraphsYMinMax()
*
* \see getGraphsXMinMax(), getGraphsYMinMax(), PlotElementPreciate
*/
struct JKQTPLOTTER_LIB_EXPORT allPlotElements {
inline bool operator()(const JKQTPPlotElement*) const { return true; };
};
/** \brief filter functor which accepts only those JKQTPPlotElement where JKQTPPlotElement::getXAxisRef()
* returns the JKQTPCoordinateAxisRef supplied to the constructor, e.g. in getGraphsXMinMax() or getGraphsYMinMax()
*
* \see getGraphsXMinMax(), getGraphsYMinMax(), PlotElementPreciate
*/
struct JKQTPLOTTER_LIB_EXPORT filterPlotElementByXAxis {
inline explicit filterPlotElementByXAxis(JKQTPCoordinateAxisRef ref_): ref(ref_) {};
inline bool operator()(const JKQTPPlotElement* el) const;
private:
JKQTPCoordinateAxisRef ref;
};
/** \brief filter functor which accepts only those JKQTPPlotElement where JKQTPPlotElement::getYAxisRef()
* returns the JKQTPCoordinateAxisRef supplied to the constructor, e.g. in getGraphsXMinMax() or getGraphsYMinMax()
*
* \see getGraphsXMinMax(), getGraphsYMinMax(), PlotElementPreciate
*/
struct JKQTPLOTTER_LIB_EXPORT filterPlotElementByYAxis {
inline explicit filterPlotElementByYAxis(JKQTPCoordinateAxisRef ref_): ref(ref_) {};
inline bool operator()(const JKQTPPlotElement* el) const;
private:
JKQTPCoordinateAxisRef ref;
};
/** \brief get the maximum and minimum x-value over all graphs in the plot /** \brief get the maximum and minimum x-value over all graphs in the plot
* \param[out] minx smallest x value * \param[out] minx smallest x value
* \param[out] maxx largest x value * \param[out] maxx largest x value
* \param[out] smallestGreaterZero smallest data point which is >0 (needed for scaling of logarithmic axes) * \param[out] smallestGreaterZero smallest data point which is >0 (needed for scaling of logarithmic axes)
* \param predicate a PlotElementPreciate, which can be used to limit the JKQTPPlotElement to be evaluated
* \returns \c true if at least one matching graph was found and evaluated succcessfully
* *
* The result is given in the two parameters which are call-by-reference parameters! * The result is given in the two parameters which are call-by-reference parameters!
*/ */
void getGraphsXMinMax(double& minx, double& maxx, double& smallestGreaterZero); bool getGraphsXMinMax(double& minx, double& maxx, double& smallestGreaterZero, const PlotElementPreciate &predicate=allPlotElements());
/** \brief get the maximum and minimum y-value over all graphs in the plot /** \brief get the maximum and minimum y-value over all graphs in the plot
* \param[out] miny smallest y value * \param[out] miny smallest y value
* \param[out] maxy largest y value * \param[out] maxy largest y value
* \param[out] smallestGreaterZero smallest data point which is >0 (needed for scaling of logarithmic axes) * \param[out] smallestGreaterZero smallest data point which is >0 (needed for scaling of logarithmic axes)
* \param predicate a PlotElementPreciate, which can be used to limit the JKQTPPlotElement to be evaluated
* \returns \c true if at least one matching graph was found and evaluated succcessfully
* *
* The result is given in the two parameters which are call-by-reference parameters! * The result is given in the two parameters which are call-by-reference parameters!
*/ */
void getGraphsYMinMax(double& miny, double& maxy, double& smallestGreaterZero); bool getGraphsYMinMax(double& miny, double& maxy, double& smallestGreaterZero, const PlotElementPreciate &predicate=allPlotElements());
/** \brief denotes, which axes to synchronize in synchronizeToMaster() */ /** \brief denotes, which axes to synchronize in synchronizeToMaster() */
@ -1226,6 +1392,9 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
* *
* \param xminn absolute minimum of x-axis * \param xminn absolute minimum of x-axis
* \param xmaxx absolute maximum of x-axis * \param xmaxx absolute maximum of x-axis
* \param affectsSecondaryAxes if \c true, the secondary axes are affectedtoo, by using a relative zooming scheme,
* i.e. if a major axis range shrinks by 50%, also the secondary ranges shrink by 50%
* [default: \c false]
* *
* \note You cannot expand the x-range outside the absolute x-range set e.g. by setAbsoluteX()! * \note You cannot expand the x-range outside the absolute x-range set e.g. by setAbsoluteX()!
* Also the range will be limited to possible values (e.g. to positive values if you use * Also the range will be limited to possible values (e.g. to positive values if you use
@ -1236,12 +1405,15 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
* *
* \see setY(), setXY(), zoomToFit(), setAbsoluteXY(), JKQTPlotter::setY() * \see setY(), setXY(), zoomToFit(), setAbsoluteXY(), JKQTPlotter::setY()
*/ */
void setX(double xminn, double xmaxx); void setX(double xminn, double xmaxx, bool affectsSecondaryAxes=false);
/** \brief sets the y-range of the plot (minimum and maximum y-value on the y-axis) /** \brief sets the y-range of the plot (minimum and maximum y-value on the y-axis)
* *
* \param yminn absolute minimum of y-axis * \param yminn absolute minimum of y-axis
* \param ymaxx absolute maximum of y-axis * \param ymaxx absolute maximum of y-axis
* \param affectsSecondaryAxes if \c true, the secondary axes are affectedtoo, by using a relative zooming scheme,
* i.e. if a major axis range shrinks by 50%, also the secondary ranges shrink by 50%
* [default: \c false]
* *
* \note You cannot expand the y-range outside the absolute y-range set e.g. by setAbsoluteY()! * \note You cannot expand the y-range outside the absolute y-range set e.g. by setAbsoluteY()!
* Also the range will be limited to possible values (e.g. to positive values if you use * Also the range will be limited to possible values (e.g. to positive values if you use
@ -1252,7 +1424,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
* *
* \see setX(), setXY(), zoomToFit(), setAbsoluteXY(), JKQTPlotter::setX() * \see setX(), setXY(), zoomToFit(), setAbsoluteXY(), JKQTPlotter::setX()
*/ */
void setY(double yminn, double ymaxx); void setY(double yminn, double ymaxx, bool affectsSecondaryAxes=false);
/** \brief sets the x- and y-range of the plot (minimum and maximum values on the x-/y-axis) /** \brief sets the x- and y-range of the plot (minimum and maximum values on the x-/y-axis)
* *
@ -1260,6 +1432,9 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
* \param xmaxx absolute maximum of x-axis * \param xmaxx absolute maximum of x-axis
* \param yminn absolute minimum of y-axis * \param yminn absolute minimum of y-axis
* \param ymaxx absolute maximum of y-axis * \param ymaxx absolute maximum of y-axis
* \param affectsSecondaryAxes if \c true, the secondary axes are affectedtoo, by using a relative zooming scheme,
* i.e. if a major axis range shrinks by 50%, also the secondary ranges shrink by 50%
* [default: \c false]
* *
* \note You cannot expand the ranges outside the absolute ranges set e.g. by setAbsoluteXY()! * \note You cannot expand the ranges outside the absolute ranges set e.g. by setAbsoluteXY()!
* Also the range will be limited to possible values (e.g. to positive values if you use * Also the range will be limited to possible values (e.g. to positive values if you use
@ -1270,7 +1445,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
* *
* \see setX(), setX(), zoomToFit(), setAbsoluteXY(), JKQTPlotter::setXY() * \see setX(), setX(), zoomToFit(), setAbsoluteXY(), JKQTPlotter::setXY()
*/ */
void setXY(double xminn, double xmaxx, double yminn, double ymaxx); void setXY(double xminn, double xmaxx, double yminn, double ymaxx, bool affectsSecondaryAxes=false);
/** \brief sets absolutely limiting x-range of the plot /** \brief sets absolutely limiting x-range of the plot
* *
@ -1873,8 +2048,12 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
/** \brief object used for the x-axis */ /** \brief object used for the x-axis */
JKQTPHorizontalAxis* xAxis; JKQTPHorizontalAxis* xAxis;
/** \brief objects used a secondary x-axes */
QMap<JKQTPCoordinateAxisRef, JKQTPHorizontalAxisBase*> secondaryXAxis;
/** \brief object used for the y-axis */ /** \brief object used for the y-axis */
JKQTPVerticalAxis* yAxis; JKQTPVerticalAxis* yAxis;
/** \brief objects used a secondary y-axes */
QMap<JKQTPCoordinateAxisRef, JKQTPVerticalAxisBase*> secondaryYAxis;
/** \brief filename for the ini file in which to save the user settings /** \brief filename for the ini file in which to save the user settings
* \see jkqtplotter_base_userprops * \see jkqtplotter_base_userprops
@ -2031,6 +2210,40 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotter: public QObject {
*/ */
double internalPlotBorderRight_notIncludingOutsidePlotSections; double internalPlotBorderRight_notIncludingOutsidePlotSections;
/** \brief <b>calculated value:</b> free space between widget top border and (plot+drawOutside) top border (including coordinate axes)
* \internal
*
* \image html plot_widget_orientation.png
*
* \note This property is an intermediate storage for calculated values. Do not change directly!
*/
double internalPlotBorderTop_notIncludingAxisAndOutsidePlotSections;
/** \brief <b>calculated value:</b> free space between widget left border and (plot+drawOutside) left border (including coordinate axes)
* \internal
*
* \image html plot_widget_orientation.png
*
* \note This property is an intermediate storage for calculated values. Do not change directly!
*/
double internalPlotBorderLeft_notIncludingAxisAndOutsidePlotSections;
/** \brief <b>calculated value:</b> free space between widget right border and (plot+drawOutside) right border (including coordinate axes)
* \internal
*
* \image html plot_widget_orientation.png
*
* \note This property is an intermediate storage for calculated values. Do not change directly!
*/
double internalPlotBorderBottom_notIncludingAxisAndOutsidePlotSections;
/** \brief <b>calculated value:</b> free space between widget bottom border and (plot+drawOutside) bottom border (including coordinate axes)
* \internal
*
* \image html plot_widget_orientation.png
*
* \note This property is an intermediate storage for calculated values. Do not change directly!
*/
double internalPlotBorderRight_notIncludingAxisAndOutsidePlotSections;
/** \brief <b>calculated value:</b> plot width in pixel inside the widget (calculated by calcPlotScaling() from plotBorderLeft, plotBorderRight and widgetWidth) /** \brief <b>calculated value:</b> plot width in pixel inside the widget (calculated by calcPlotScaling() from plotBorderLeft, plotBorderRight and widgetWidth)
* *
* \image html plot_widget_orientation.png * \image html plot_widget_orientation.png

View File

@ -31,6 +31,7 @@ JKQTBasePlotterStyle::JKQTBasePlotterStyle():
keyStyle(*this), keyStyle(*this),
xAxisStyle(*this), xAxisStyle(*this),
yAxisStyle(*this), yAxisStyle(*this),
secondaryAxisSeparation(6),
rightColorbarAxisStyle(*this), rightColorbarAxisStyle(*this),
topColorbarAxisStyle(*this), topColorbarAxisStyle(*this),
graphsStyle(*this) graphsStyle(*this)
@ -63,6 +64,7 @@ void JKQTBasePlotterStyle::loadSettings(const QSettings &settings, const QString
defaultTextColor=jkqtp_String2QColor(settings.value(group+"text_default_color", jkqtp_QColor2String(defaultStyle.defaultTextColor)).toString()); defaultTextColor=jkqtp_String2QColor(settings.value(group+"text_default_color", jkqtp_QColor2String(defaultStyle.defaultTextColor)).toString());
defaultFontSize=settings.value(group+"text_default_size", defaultStyle.defaultFontSize).toDouble(); defaultFontSize=settings.value(group+"text_default_size", defaultStyle.defaultFontSize).toDouble();
defaultFontName=settings.value(group+"text_default_font_name", defaultStyle.defaultFontName).toString(); defaultFontName=settings.value(group+"text_default_font_name", defaultStyle.defaultFontName).toString();
secondaryAxisSeparation=settings.value(group+"secondary_axis_separation", defaultStyle.secondaryAxisSeparation).toDouble();
keyStyle.loadSettings(settings, group+"key/", defaultStyle.keyStyle); keyStyle.loadSettings(settings, group+"key/", defaultStyle.keyStyle);
xAxisStyle.loadSettings(settings, group+"axis_x/", defaultStyle.xAxisStyle); xAxisStyle.loadSettings(settings, group+"axis_x/", defaultStyle.xAxisStyle);
@ -101,6 +103,7 @@ void JKQTBasePlotterStyle::saveSettings(QSettings &settings, const QString &grou
settings.setValue(group+"plot_frame_color", jkqtp_QColor2String(plotFrameColor)); settings.setValue(group+"plot_frame_color", jkqtp_QColor2String(plotFrameColor));
settings.setValue(group+"plot_frame_width", plotFrameWidth); settings.setValue(group+"plot_frame_width", plotFrameWidth);
settings.setValue(group+"plot_frame_rounded", plotFrameRounding); settings.setValue(group+"plot_frame_rounded", plotFrameRounding);
settings.setValue(group+"secondary_axis_separation", secondaryAxisSeparation);
keyStyle.saveSettings(settings, group+"key/"); keyStyle.saveSettings(settings, group+"key/");
xAxisStyle.saveSettings(settings, group+"axis_x/"); xAxisStyle.saveSettings(settings, group+"axis_x/");

View File

@ -160,6 +160,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTBasePlotterStyle {
JKQTPCoordinateAxisStyle xAxisStyle; JKQTPCoordinateAxisStyle xAxisStyle;
/** \brief style of the y-axis of the main coordinate system */ /** \brief style of the y-axis of the main coordinate system */
JKQTPCoordinateAxisStyle yAxisStyle; JKQTPCoordinateAxisStyle yAxisStyle;
/** \brief separation between two seondary axes in pt */
double secondaryAxisSeparation;
/** \brief style of the coordinate axes used to display colorbars in the right */ /** \brief style of the coordinate axes used to display colorbars in the right */
JKQTPColorbarCoordinateAxisStyle rightColorbarAxisStyle; JKQTPColorbarCoordinateAxisStyle rightColorbarAxisStyle;
/** \brief style of the coordinate axes used to display colorbars at the top */ /** \brief style of the coordinate axes used to display colorbars at the top */

View File

@ -82,6 +82,7 @@ void JKQTPCoordinateAxis::setParent(JKQTBasePlotter* parent) {
void JKQTPCoordinateAxis::redrawPlot() { void JKQTPCoordinateAxis::redrawPlot() {
//if (paramsChanged) { //if (paramsChanged) {
calcPlotScaling(); calcPlotScaling();
parent->updateSecondaryAxes();
parent->redrawPlot(); parent->redrawPlot();
//} //}
} }
@ -1140,6 +1141,18 @@ void JKQTPCoordinateAxis::setTickLabelColor(QColor c) {
redrawPlot(); redrawPlot();
} }
void JKQTPCoordinateAxis::setColor(QColor c)
{
setAxisColor(c);
setGridColor(c.lighter());
setMinorGridColor(c.lighter());
setLabelColor(c);
setMinorTickColor(c);
setMinorTickLabelColor(c);
setTickColor(c);
setTickLabelColor(c);
}
std::pair<QSizeF,QSizeF> JKQTPCoordinateAxis::getSize0(JKQTPEnhancedPainter &/*painter*/) std::pair<QSizeF,QSizeF> JKQTPCoordinateAxis::getSize0(JKQTPEnhancedPainter &/*painter*/)
{ {
return std::pair<QSizeF,QSizeF>(QSizeF(0,0),QSizeF(0,0)); return std::pair<QSizeF,QSizeF>(QSizeF(0,0),QSizeF(0,0));
@ -1276,7 +1289,7 @@ double JKQTPCoordinateAxis::getZeroAxisPos(bool *drawZeroAxis) {
JKQTPVerticalAxis::JKQTPVerticalAxis(JKQTBasePlotter* parent): JKQTPVerticalAxisBase::JKQTPVerticalAxisBase(JKQTBasePlotter* parent):
JKQTPCoordinateAxis(parent) JKQTPCoordinateAxis(parent)
{ {
//axisPrefix="yaxis_"; //axisPrefix="yaxis_";
@ -1288,15 +1301,8 @@ JKQTPVerticalAxis::JKQTPVerticalAxis(JKQTBasePlotter* parent):
} }
} }
double JKQTPVerticalAxis::getParentPlotWidth() const {
return parent->getPlotHeight();
}
double JKQTPVerticalAxis::getParentPlotOffset() const { std::pair<QSizeF,QSizeF> JKQTPVerticalAxisBase::getSize0(JKQTPEnhancedPainter& painter) {
return parent->getInternalPlotBorderTop();
}
std::pair<QSizeF,QSizeF> JKQTPVerticalAxis::getSize0(JKQTPEnhancedPainter& painter) {
if (axisStyle.drawMode0==JKQTPCADMnone) return std::pair<QSizeF,QSizeF>(QSizeF(0,0),QSizeF(0,0)); if (axisStyle.drawMode0==JKQTPCADMnone) return std::pair<QSizeF,QSizeF>(QSizeF(0,0),QSizeF(0,0));
double ptwidth=0; double ptwidth=0;
double ptwidth_r=0; double ptwidth_r=0;
@ -1326,7 +1332,7 @@ std::pair<QSizeF,QSizeF> JKQTPVerticalAxis::getSize0(JKQTPEnhancedPainter& paint
} }
QSizeF JKQTPVerticalAxis::getSize1(JKQTPEnhancedPainter& painter) { QSizeF JKQTPVerticalAxisBase::getSize1(JKQTPEnhancedPainter& painter) {
if (axisStyle.drawMode1==JKQTPCADMnone) return QSize(0,0); if (axisStyle.drawMode1==JKQTPCADMnone) return QSize(0,0);
double ptwidth=axisStyle.axisLineOffset; double ptwidth=axisStyle.axisLineOffset;
const double arrowSize=((axisStyle.drawMode1&(JKQTPCADMMinArrow|JKQTPCADMMinFilledArrow|JKQTPCADMMaxArrow|JKQTPCADMMaxFilledArrow))!=int(0))?(axisStyle.getArrowSize(painter, parent)/2.0):0.0; const double arrowSize=((axisStyle.drawMode1&(JKQTPCADMMinArrow|JKQTPCADMMinFilledArrow|JKQTPCADMMaxArrow|JKQTPCADMMaxFilledArrow))!=int(0))?(axisStyle.getArrowSize(painter, parent)/2.0):0.0;
@ -1346,7 +1352,7 @@ QSizeF JKQTPVerticalAxis::getSize1(JKQTPEnhancedPainter& painter) {
return QSizeF(qMax(parent->pt2px(painter, ptwidth)+labwidth, arrowSize), getParentPlotWidth()).expandedTo(getSize0(painter).first); return QSizeF(qMax(parent->pt2px(painter, ptwidth)+labwidth, arrowSize), getParentPlotWidth()).expandedTo(getSize0(painter).first);
} }
QSizeF JKQTPVerticalAxis::getSize2(JKQTPEnhancedPainter& painter) { QSizeF JKQTPVerticalAxisBase::getSize2(JKQTPEnhancedPainter& painter) {
if (axisStyle.drawMode2==JKQTPCADMnone) return QSize(0,0); if (axisStyle.drawMode2==JKQTPCADMnone) return QSize(0,0);
double ptwidth=axisStyle.axisLineOffset; double ptwidth=axisStyle.axisLineOffset;
const double arrowSize=((axisStyle.drawMode2&(JKQTPCADMMinArrow|JKQTPCADMMinFilledArrow|JKQTPCADMMaxArrow|JKQTPCADMMaxFilledArrow))!=int(0))?(axisStyle.getArrowSize(painter, parent)/2.0):0.0; const double arrowSize=((axisStyle.drawMode2&(JKQTPCADMMinArrow|JKQTPCADMMinFilledArrow|JKQTPCADMMaxArrow|JKQTPCADMMaxFilledArrow))!=int(0))?(axisStyle.getArrowSize(painter, parent)/2.0):0.0;
@ -1366,26 +1372,7 @@ QSizeF JKQTPVerticalAxis::getSize2(JKQTPEnhancedPainter& painter) {
return QSizeF(qMax(arrowSize, parent->pt2px(painter, ptwidth)+labwidth), getParentPlotWidth()).expandedTo(getSize0(painter).second); return QSizeF(qMax(arrowSize, parent->pt2px(painter, ptwidth)+labwidth), getParentPlotWidth()).expandedTo(getSize0(painter).second);
} }
void JKQTPVerticalAxisBase::drawGrids(JKQTPEnhancedPainter& painter) {
double JKQTPVerticalAxis::getParentOtheraxisOffset() const {
return parent->x2p(parent->getXMin());
}
double JKQTPVerticalAxis::parentOtherAxisX2P(double x) const
{
return parent->x2p(x);
}
double JKQTPVerticalAxis::getParentOtheraxisWidth() const {
return fabs(parent->x2p(parent->getXMax())-parent->x2p(parent->getXMin()));
}
bool JKQTPVerticalAxis::getParentOtheraxisInverted() const
{
return parent->getXAxis()->getInverted();
}
void JKQTPVerticalAxis::drawGrids(JKQTPEnhancedPainter& painter) {
//qDebug()<<" start JKQTPVerticalAxis::drawGrids("; //qDebug()<<" start JKQTPVerticalAxis::drawGrids(";
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
QPen pg=painter.pen(); QPen pg=painter.pen();
@ -1459,7 +1446,7 @@ void JKQTPVerticalAxis::drawGrids(JKQTPEnhancedPainter& painter) {
//qDebug()<<" end JKQTPVerticalAxis::drawGrids("; //qDebug()<<" end JKQTPVerticalAxis::drawGrids(";
} }
void JKQTPVerticalAxis::drawTickLabel1(JKQTPEnhancedPainter &painter, double xx, double yy, double labelOffset, const QString& label, double fontSize, bool isMinor) void JKQTPVerticalAxisBase::drawTickLabel1(JKQTPEnhancedPainter &painter, double xx, double yy, double labelOffset, const QString& label, double fontSize, bool isMinor)
{ {
getParentMathText()->setFontSize(fontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontSize(fontSize*parent->getFontSizeMultiplier());
getParentMathText()->setFontSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->setFontSpecial(getParent()->getCurrentPlotterStyle().defaultFontName);
@ -1498,7 +1485,7 @@ void JKQTPVerticalAxis::drawTickLabel1(JKQTPEnhancedPainter &painter, double xx,
} }
} }
void JKQTPVerticalAxis::drawTickLabel2(JKQTPEnhancedPainter &painter, double xx, double yy, double labelOffset, const QString &label, double fontSize, bool isMinor) void JKQTPVerticalAxisBase::drawTickLabel2(JKQTPEnhancedPainter &painter, double xx, double yy, double labelOffset, const QString &label, double fontSize, bool isMinor)
{ {
getParentMathText()->setFontSize(fontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontSize(fontSize*parent->getFontSizeMultiplier());
getParentMathText()->setFontSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->setFontSpecial(getParent()->getCurrentPlotterStyle().defaultFontName);
@ -1540,7 +1527,7 @@ void JKQTPVerticalAxis::drawTickLabel2(JKQTPEnhancedPainter &painter, double xx,
} }
void JKQTPVerticalAxis::drawAxisLabel1(JKQTPEnhancedPainter &painter, double left, double bottom, QSizeF labelMax, JKQTPCADrawMode drawMode) { void JKQTPVerticalAxisBase::drawAxisLabel1(JKQTPEnhancedPainter &painter, double left, double bottom, QSizeF labelMax, JKQTPCADrawMode drawMode) {
double labelOffset=parent->pt2px(painter, axisStyle.labelDistance); double labelOffset=parent->pt2px(painter, axisStyle.labelDistance);
if (drawMode.testFlag(JKQTPCADMTicks)) labelOffset+=parent->pt2px(painter, axisStyle.tickOutsideLength); if (drawMode.testFlag(JKQTPCADMTicks)) labelOffset+=parent->pt2px(painter, axisStyle.tickOutsideLength);
if (drawMode.testFlag(JKQTPCADMTickLabels)) { if (drawMode.testFlag(JKQTPCADMTickLabels)) {
@ -1586,7 +1573,7 @@ void JKQTPVerticalAxis::drawAxisLabel1(JKQTPEnhancedPainter &painter, double lef
painter.resetTransform(); painter.resetTransform();
} }
void JKQTPVerticalAxis::drawAxisLabel2(JKQTPEnhancedPainter &painter, double right, double bottom, QSizeF labelMax, JKQTPCADrawMode drawMode) { void JKQTPVerticalAxisBase::drawAxisLabel2(JKQTPEnhancedPainter &painter, double right, double bottom, QSizeF labelMax, JKQTPCADrawMode drawMode) {
double labelOffset=parent->pt2px(painter, axisStyle.labelDistance); double labelOffset=parent->pt2px(painter, axisStyle.labelDistance);
if (drawMode.testFlag(JKQTPCADMTicks)) labelOffset+=parent->pt2px(painter, axisStyle.tickOutsideLength); if (drawMode.testFlag(JKQTPCADMTicks)) labelOffset+=parent->pt2px(painter, axisStyle.tickOutsideLength);
if (drawMode.testFlag(JKQTPCADMTickLabels)) { if (drawMode.testFlag(JKQTPCADMTickLabels)) {
@ -1633,7 +1620,7 @@ void JKQTPVerticalAxis::drawAxisLabel2(JKQTPEnhancedPainter &painter, double rig
painter.resetTransform(); painter.resetTransform();
} }
void JKQTPVerticalAxis::drawAxes(JKQTPEnhancedPainter& painter) { void JKQTPVerticalAxisBase::drawAxes(JKQTPEnhancedPainter& painter, int move1, int move2) {
#ifdef JKQTBP_AUTOTIMER #ifdef JKQTBP_AUTOTIMER
JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes()").arg(objectName())); JKQTPAutoOutputTimer jkaat(QString("JKQTPEnhancedPainter[%1]::drawAxes()").arg(objectName()));
#endif #endif
@ -1657,8 +1644,8 @@ void JKQTPVerticalAxis::drawAxes(JKQTPEnhancedPainter& painter) {
right=getParentOtheraxisOffset()+getParentOtheraxisWidth();//; right=getParentOtheraxisOffset()+getParentOtheraxisWidth();//;
} }
// move axes outside plot rectangle, if required // move axes outside plot rectangle, if required
left-=parent->pt2px(painter, axisStyle.axisLineOffset); left-=parent->pt2px(painter, axisStyle.axisLineOffset)+move1;
right+=parent->pt2px(painter, axisStyle.axisLineOffset); right+=parent->pt2px(painter, axisStyle.axisLineOffset)+move2;
double ticklabelOffset1PT=axisStyle.tickLabelDistance; // offset of tick labels from axis 1 double ticklabelOffset1PT=axisStyle.tickLabelDistance; // offset of tick labels from axis 1
@ -1912,9 +1899,56 @@ void JKQTPVerticalAxis::drawAxes(JKQTPEnhancedPainter& painter) {
JKQTPVerticalAxis::JKQTPVerticalAxis(JKQTBasePlotter* parent, JKQTPCoordinateAxisRef otherAxisRef_):
JKQTPVerticalAxisBase(parent), otherAxisRef(otherAxisRef_)
{
//axisPrefix="yaxis_";
scaleSign=-1;
if (parent) {
axisStyle=parent->getCurrentPlotterStyle().yAxisStyle;
} else {
axisStyle=JKQTPGetSystemDefaultBaseStyle().yAxisStyle;
}
}
double JKQTPVerticalAxis::getParentPlotWidth() const {
return parent->getPlotHeight();
}
double JKQTPVerticalAxis::getParentPlotOffset() const {
return parent->getInternalPlotBorderTop();
}
double JKQTPVerticalAxis::getParentOtheraxisOffset() const {
return getOtherAxis()->x2p(getOtherAxis()->getMin());
}
double JKQTPVerticalAxis::parentOtherAxisX2P(double x) const
{
return getOtherAxis()->x2p(x);
}
JKQTPCoordinateAxisRef JKQTPVerticalAxis::getOtherAxisRef() const {
return otherAxisRef;
}
const JKQTPCoordinateAxis *JKQTPVerticalAxis::getOtherAxis() const {
return parent->getXAxis(otherAxisRef);
}
double JKQTPVerticalAxis::getParentOtheraxisWidth() const {
return fabs(getOtherAxis()->x2p(getOtherAxis()->getMax())-getOtherAxis()->x2p(getOtherAxis()->getMin()));
}
bool JKQTPVerticalAxis::getParentOtheraxisInverted() const
{
return getOtherAxis()->getInverted();
}
JKQTPVerticalIndependentAxis::JKQTPVerticalIndependentAxis(double _axisOffset, double _axisWidth, double _otherAxisOffset, double _otherAxisWidth, JKQTBasePlotter* parent): JKQTPVerticalIndependentAxis::JKQTPVerticalIndependentAxis(double _axisOffset, double _axisWidth, double _otherAxisOffset, double _otherAxisWidth, JKQTBasePlotter* parent):
JKQTPVerticalAxis(parent), JKQTPVerticalAxisBase(parent),
axisOffset(_axisOffset), axisOffset(_axisOffset),
axisWidth(_axisWidth), axisWidth(_axisWidth),
otherAxisWidth(_otherAxisOffset), otherAxisWidth(_otherAxisOffset),
@ -1992,7 +2026,7 @@ double JKQTPVerticalIndependentAxis::parentOtherAxisX2P(double x) const
JKQTPHorizontalAxis::JKQTPHorizontalAxis(JKQTBasePlotter* parent): JKQTPHorizontalAxisBase::JKQTPHorizontalAxisBase(JKQTBasePlotter* parent):
JKQTPCoordinateAxis(parent) JKQTPCoordinateAxis(parent)
{ {
//axisPrefix="xaxis_"; //axisPrefix="xaxis_";
@ -2005,15 +2039,8 @@ JKQTPHorizontalAxis::JKQTPHorizontalAxis(JKQTBasePlotter* parent):
} }
double JKQTPHorizontalAxis::getParentPlotWidth() const {
return parent->getPlotWidth();
}
double JKQTPHorizontalAxis::getParentPlotOffset() const { std::pair<QSizeF,QSizeF> JKQTPHorizontalAxisBase::getSize0(JKQTPEnhancedPainter& painter) {
return parent->getInternalPlotBorderLeft();
}
std::pair<QSizeF,QSizeF> JKQTPHorizontalAxis::getSize0(JKQTPEnhancedPainter& painter) {
if (axisStyle.drawMode0==JKQTPCADMnone) return std::pair<QSizeF,QSizeF>(QSizeF(0,0),QSizeF(0,0)); if (axisStyle.drawMode0==JKQTPCADMnone) return std::pair<QSizeF,QSizeF>(QSizeF(0,0),QSizeF(0,0));
double ptheight=0; double ptheight=0;
double ptheight_t=0; double ptheight_t=0;
@ -2043,7 +2070,7 @@ std::pair<QSizeF,QSizeF> JKQTPHorizontalAxis::getSize0(JKQTPEnhancedPainter& pai
); );
} }
QSizeF JKQTPHorizontalAxis::getSize1(JKQTPEnhancedPainter& painter) { QSizeF JKQTPHorizontalAxisBase::getSize1(JKQTPEnhancedPainter& painter) {
if (axisStyle.drawMode1==JKQTPCADMnone) return QSize(0,0); if (axisStyle.drawMode1==JKQTPCADMnone) return QSize(0,0);
double ptheight=axisStyle.axisLineOffset; double ptheight=axisStyle.axisLineOffset;
const double arrowSize=((axisStyle.drawMode1&(JKQTPCADMMinArrow|JKQTPCADMMinFilledArrow|JKQTPCADMMaxArrow|JKQTPCADMMaxFilledArrow))!=int(0))?(axisStyle.getArrowSize(painter, parent)/2.0):0.0; const double arrowSize=((axisStyle.drawMode1&(JKQTPCADMMinArrow|JKQTPCADMMinFilledArrow|JKQTPCADMMaxArrow|JKQTPCADMMaxFilledArrow))!=int(0))?(axisStyle.getArrowSize(painter, parent)/2.0):0.0;
@ -2063,7 +2090,7 @@ QSizeF JKQTPHorizontalAxis::getSize1(JKQTPEnhancedPainter& painter) {
return QSizeF(getParentPlotWidth(), qMax(arrowSize,parent->pt2px(painter, ptheight)+labheight)).expandedTo(getSize0(painter).first); return QSizeF(getParentPlotWidth(), qMax(arrowSize,parent->pt2px(painter, ptheight)+labheight)).expandedTo(getSize0(painter).first);
} }
QSizeF JKQTPHorizontalAxis::getSize2(JKQTPEnhancedPainter& painter) { QSizeF JKQTPHorizontalAxisBase::getSize2(JKQTPEnhancedPainter& painter) {
if (axisStyle.drawMode2==JKQTPCADMnone) return QSize(0,0); if (axisStyle.drawMode2==JKQTPCADMnone) return QSize(0,0);
double ptheight=axisStyle.axisLineOffset; double ptheight=axisStyle.axisLineOffset;
const double arrowSize=((axisStyle.drawMode2&(JKQTPCADMMinArrow|JKQTPCADMMinFilledArrow|JKQTPCADMMaxArrow|JKQTPCADMMaxFilledArrow))!=int(0))?(axisStyle.getArrowSize(painter, parent)/2.0):0.0; const double arrowSize=((axisStyle.drawMode2&(JKQTPCADMMinArrow|JKQTPCADMMinFilledArrow|JKQTPCADMMaxArrow|JKQTPCADMMaxFilledArrow))!=int(0))?(axisStyle.getArrowSize(painter, parent)/2.0):0.0;
@ -2084,24 +2111,7 @@ QSizeF JKQTPHorizontalAxis::getSize2(JKQTPEnhancedPainter& painter) {
} }
double JKQTPHorizontalAxis::getParentOtheraxisOffset() const { void JKQTPHorizontalAxisBase::drawGrids(JKQTPEnhancedPainter& painter) {
return parent->y2p(parent->getYMax());
}
double JKQTPHorizontalAxis::parentOtherAxisX2P(double x) const
{
return parent->y2p(x);
}
double JKQTPHorizontalAxis::getParentOtheraxisWidth() const {
return fabs(parent->y2p(parent->getYMax())-parent->y2p(parent->getYMin()));
}
bool JKQTPHorizontalAxis::getParentOtheraxisInverted() const
{
return parent->getYAxis()->getInverted();
}
void JKQTPHorizontalAxis::drawGrids(JKQTPEnhancedPainter& painter) {
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
//double right=x2p(axismax); //double right=x2p(axismax);
//double left=x2p(axismin); //double left=x2p(axismin);
@ -2165,7 +2175,7 @@ void JKQTPHorizontalAxis::drawGrids(JKQTPEnhancedPainter& painter) {
} }
void JKQTPHorizontalAxis::drawTickLabel1(JKQTPEnhancedPainter &painter, double xx, double yy, double labelOffset, const QString &label, double fontSize, double ascentMax, double /*descentMax*/, bool isMinor) void JKQTPHorizontalAxisBase::drawTickLabel1(JKQTPEnhancedPainter &painter, double xx, double yy, double labelOffset, const QString &label, double fontSize, double ascentMax, double /*descentMax*/, bool isMinor)
{ {
getParentMathText()->setFontSize(fontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontSize(fontSize*parent->getFontSizeMultiplier());
getParentMathText()->setFontSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->setFontSpecial(getParent()->getCurrentPlotterStyle().defaultFontName);
@ -2194,7 +2204,7 @@ void JKQTPHorizontalAxis::drawTickLabel1(JKQTPEnhancedPainter &painter, double x
} }
} }
void JKQTPHorizontalAxis::drawTickLabel2(JKQTPEnhancedPainter &painter, double xx, double yy, double labelOffset, const QString &label, double fontSize, double /*ascentMax*/, double descentMax, bool isMinor) void JKQTPHorizontalAxisBase::drawTickLabel2(JKQTPEnhancedPainter &painter, double xx, double yy, double labelOffset, const QString &label, double fontSize, double /*ascentMax*/, double descentMax, bool isMinor)
{ {
getParentMathText()->setFontSize(fontSize*parent->getFontSizeMultiplier()); getParentMathText()->setFontSize(fontSize*parent->getFontSizeMultiplier());
getParentMathText()->setFontSpecial(getParent()->getCurrentPlotterStyle().defaultFontName); getParentMathText()->setFontSpecial(getParent()->getCurrentPlotterStyle().defaultFontName);
@ -2223,7 +2233,7 @@ void JKQTPHorizontalAxis::drawTickLabel2(JKQTPEnhancedPainter &painter, double x
} }
void JKQTPHorizontalAxis::drawAxisLabel1(JKQTPEnhancedPainter &painter, double left, double bottom, QSizeF labelMax, JKQTPCADrawMode drawMode) { void JKQTPHorizontalAxisBase::drawAxisLabel1(JKQTPEnhancedPainter &painter, double left, double bottom, QSizeF labelMax, JKQTPCADrawMode drawMode) {
double labelOffset=parent->pt2px(painter, axisStyle.labelDistance); double labelOffset=parent->pt2px(painter, axisStyle.labelDistance);
if (drawMode.testFlag(JKQTPCADMTicks)) labelOffset+=parent->pt2px(painter, axisStyle.tickOutsideLength); if (drawMode.testFlag(JKQTPCADMTicks)) labelOffset+=parent->pt2px(painter, axisStyle.tickOutsideLength);
if (drawMode.testFlag(JKQTPCADMTickLabels)) { if (drawMode.testFlag(JKQTPCADMTickLabels)) {
@ -2269,12 +2279,12 @@ void JKQTPHorizontalAxis::drawAxisLabel1(JKQTPEnhancedPainter &painter, double l
} }
} }
void JKQTPHorizontalAxis::drawAxisLabel2(JKQTPEnhancedPainter &painter, double left, double top, QSizeF labelMax, JKQTPCADrawMode drawMode) { void JKQTPHorizontalAxisBase::drawAxisLabel2(JKQTPEnhancedPainter &painter, double left, double top, QSizeF labelMax, JKQTPCADrawMode drawMode) {
double labelOffset=parent->pt2px(painter, axisStyle.labelDistance); double labelOffset=parent->pt2px(painter, axisStyle.labelDistance);
if (drawMode.testFlag(JKQTPCADMTicks)) labelOffset+=parent->pt2px(painter, axisStyle.tickOutsideLength); if (drawMode.testFlag(JKQTPCADMTicks)) labelOffset+=parent->pt2px(painter, axisStyle.tickOutsideLength);
if (drawMode.testFlag(JKQTPCADMTickLabels)) { if (drawMode.testFlag(JKQTPCADMTickLabels)) {
labelOffset+=parent->pt2px(painter, axisStyle.tickLabelDistance); labelOffset+=parent->pt2px(painter, axisStyle.tickLabelDistance);
labelOffset+=labelMax.width();//+labelMax.height(); labelOffset+=labelMax.height();//+labelMax.height();
} }
@ -2314,7 +2324,7 @@ void JKQTPHorizontalAxis::drawAxisLabel2(JKQTPEnhancedPainter &painter, double l
//painter.resetTransform(); //painter.resetTransform();
} }
void JKQTPHorizontalAxis::drawAxes(JKQTPEnhancedPainter& painter) { void JKQTPHorizontalAxisBase::drawAxes(JKQTPEnhancedPainter& painter, int move1, int move2) {
#ifdef JKQTBP_AUTOTIMER #ifdef JKQTBP_AUTOTIMER
JKQTPAutoOutputTimer jkaat(QString("JKQTPHorizontalAxis[%1]::drawAxes()").arg(objectName())); JKQTPAutoOutputTimer jkaat(QString("JKQTPHorizontalAxis[%1]::drawAxes()").arg(objectName()));
#endif #endif
@ -2338,8 +2348,8 @@ void JKQTPHorizontalAxis::drawAxes(JKQTPEnhancedPainter& painter) {
bottom=getParentOtheraxisOffset()+getParentOtheraxisWidth();//; bottom=getParentOtheraxisOffset()+getParentOtheraxisWidth();//;
} }
// move axes outside plot rectangle, if required // move axes outside plot rectangle, if required
top-=parent->pt2px(painter, axisStyle.axisLineOffset); top-=parent->pt2px(painter, axisStyle.axisLineOffset)+move2;
bottom+=parent->pt2px(painter, axisStyle.axisLineOffset); bottom+=parent->pt2px(painter, axisStyle.axisLineOffset)+move1;
double ticklabelOffset1PT=axisStyle.tickLabelDistance; // offset of tick labels from axis 1 double ticklabelOffset1PT=axisStyle.tickLabelDistance; // offset of tick labels from axis 1
double minorticklabelOffset1PT=axisStyle.tickLabelDistance; // offset ofminor tick labels from axis 1 double minorticklabelOffset1PT=axisStyle.tickLabelDistance; // offset ofminor tick labels from axis 1
@ -2584,6 +2594,53 @@ void JKQTPHorizontalAxis::drawAxes(JKQTPEnhancedPainter& painter) {
JKQTPHorizontalAxis::JKQTPHorizontalAxis(JKQTBasePlotter* parent, JKQTPCoordinateAxisRef otherAxisRef_):
JKQTPHorizontalAxisBase(parent), otherAxisRef(otherAxisRef_)
{
//axisPrefix="xaxis_";
scaleSign=1;
if (parent) {
axisStyle=parent->getCurrentPlotterStyle().xAxisStyle;
} else {
axisStyle=JKQTPGetSystemDefaultBaseStyle().xAxisStyle;
}
}
double JKQTPHorizontalAxis::getParentPlotWidth() const {
return parent->getPlotWidth();
}
double JKQTPHorizontalAxis::getParentPlotOffset() const {
return parent->getInternalPlotBorderLeft();
}
double JKQTPHorizontalAxis::getParentOtheraxisOffset() const {
return getOtherAxis()->x2p(getOtherAxis()->getMax());
}
double JKQTPHorizontalAxis::parentOtherAxisX2P(double x) const
{
return parent->y2p(x);
}
JKQTPCoordinateAxisRef JKQTPHorizontalAxis::getOtherAxisRef() const
{
return otherAxisRef;
}
const JKQTPCoordinateAxis *JKQTPHorizontalAxis::getOtherAxis() const {
return parent->getYAxis(otherAxisRef);
}
double JKQTPHorizontalAxis::getParentOtheraxisWidth() const {
return fabs(getOtherAxis()->x2p(getOtherAxis()->getMax())-getOtherAxis()->x2p(getOtherAxis()->getMin()));
}
bool JKQTPHorizontalAxis::getParentOtheraxisInverted() const
{
return getOtherAxis()->getInverted();
}

View File

@ -36,6 +36,19 @@
// forward declarations // forward declarations
class JKQTBasePlotter; class JKQTBasePlotter;
/*! \brief named references for different oordinate axes in the plot
\ingroup jkqtpplottersupprt
*/
enum JKQTPCoordinateAxes: uint8_t {
JKQTPPrimaryAxis=0,
JKQTPSecondaryAxis=1
};
/*! \brief type for indexing coordinate axes in a plot
\ingroup jkqtpplottersupprt
*/
typedef JKQTPCoordinateAxes JKQTPCoordinateAxisRef;
/*! \brief this virtual class is the base for any type of coordinate axis, to be drawn by JKQTBasePlotter. /*! \brief this virtual class is the base for any type of coordinate axis, to be drawn by JKQTBasePlotter.
\ingroup jkqtpbaseplotter_elements \ingroup jkqtpbaseplotter_elements
@ -238,8 +251,13 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPCoordinateAxis: public QObject {
/** \brief returns the size of the right/top axis in pixels */ /** \brief returns the size of the right/top axis in pixels */
virtual QSizeF getSize2(JKQTPEnhancedPainter& painter)=0; virtual QSizeF getSize2(JKQTPEnhancedPainter& painter)=0;
/** \brief draw axes */ /** \brief draw the axes
virtual void drawAxes(JKQTPEnhancedPainter& painter)=0; *
* \param painter the painter to use for drawing
* \param move1 offset in pixels on the major side (horizontal: bottom, vertical: left)
* \param move2 offset in pixels on the secondary side (horizontal: top, vertical: right)
*/
virtual void drawAxes(JKQTPEnhancedPainter& painter, int move1=0, int move2=0)=0;
/** \brief draw grids */ /** \brief draw grids */
virtual void drawGrids(JKQTPEnhancedPainter& painter)=0; virtual void drawGrids(JKQTPEnhancedPainter& painter)=0;
@ -650,6 +668,8 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPCoordinateAxis: public QObject {
void setTickColor(QColor c); void setTickColor(QColor c);
/** \copydoc JKQTPCoordinateAxisStyle::tickLabelColor */ /** \copydoc JKQTPCoordinateAxisStyle::tickLabelColor */
void setTickLabelColor(QColor c) ; void setTickLabelColor(QColor c) ;
/** \brief sets all colors (line, ticks, label, ...) of the axis */
void setColor(QColor c) ;
protected: protected:
/** \brief returns the size of the zero axis in pixels, the first part of the return-value is the lhs size and the second part the rhs size */ /** \brief returns the size of the zero axis in pixels, the first part of the return-value is the lhs size and the second part the rhs size */
@ -852,20 +872,32 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPCoordinateAxis: public QObject {
/*! \brief implements a vertical axis, based on JKQTPCoordinateAxis (for most of documentation: see JKQTPCoordinateAxis). /*! \brief base class for vertical axes, based on JKQTPCoordinateAxis (for most of documentation: see JKQTPCoordinateAxis).
\ingroup jkqtpbaseplotter_elements \ingroup jkqtpbaseplotter_elements
The positioning of the different axis elements depends on the psition of the "other" axis (here x-axis), The positioning of the different axis elements depends on the psition of the "other" axis (i.e. a horizontal/x-axis),
i.e. the corresponding vertical axis: i.e. the corresponding vertical axis:
\image html JKQTPHorizontalAxisPositioning.png \image html JKQTPVerticalAxisPositioning.png
But this "other>" axis is not defined here, but has to be defined in derived classes by immplementing the corresponding
pure virtual functions:
- getParentPlotWidth()
- getParentPlotOffset()
- getParentOtheraxisWidth()
- getParentOtheraxisInverted()
- getParentOtheraxisOffset()
- parentOtherAxisX2P()
.
\see JKQTPHorizontalAxisBase
*/ */
class JKQTPLOTTER_LIB_EXPORT JKQTPVerticalAxis: public JKQTPCoordinateAxis { class JKQTPLOTTER_LIB_EXPORT JKQTPVerticalAxisBase: public JKQTPCoordinateAxis {
Q_OBJECT Q_OBJECT
protected: protected:
public: public:
/** \brief class constructor */ /** \brief class constructor */
JKQTPVerticalAxis(JKQTBasePlotter* parent); JKQTPVerticalAxisBase(JKQTBasePlotter* parent);
/** \brief returns the size of the left axis in pixels */ /** \brief returns the size of the left axis in pixels */
virtual QSizeF getSize1(JKQTPEnhancedPainter& painter) override; virtual QSizeF getSize1(JKQTPEnhancedPainter& painter) override;
@ -874,25 +906,12 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPVerticalAxis: public JKQTPCoordinateAxis {
virtual QSizeF getSize2(JKQTPEnhancedPainter& painter) override; virtual QSizeF getSize2(JKQTPEnhancedPainter& painter) override;
/** copydoc JKQTPCoordinateAxis::drawAxes() */ /** copydoc JKQTPCoordinateAxis::drawAxes() */
virtual void drawAxes(JKQTPEnhancedPainter& painter) override; virtual void drawAxes(JKQTPEnhancedPainter& painter, int move1=0, int move2=0) override;
/** copydoc JKQTPCoordinateAxis::drawGrids() */ /** copydoc JKQTPCoordinateAxis::drawGrids() */
virtual void drawGrids(JKQTPEnhancedPainter& painter) override; virtual void drawGrids(JKQTPEnhancedPainter& painter) override;
/** copydoc JKQTPCoordinateAxis::getParentPlotWidth() */
virtual double getParentPlotWidth() const override;
/** copydoc JKQTPCoordinateAxis::getParentPlotOffset() */
virtual double getParentPlotOffset() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisWidth() */
virtual double getParentOtheraxisWidth() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisInverted() */
virtual bool getParentOtheraxisInverted() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisOffset() */
virtual double getParentOtheraxisOffset() const override;
/** copydoc JKQTPCoordinateAxis::parentOtherAxisX2P() */
virtual double parentOtherAxisX2P(double x) const override;
protected: protected:
/** copydoc JKQTPCoordinateAxis::getSize0() */ /** copydoc JKQTPCoordinateAxis::getSize0() */
virtual std::pair<QSizeF,QSizeF> getSize0(JKQTPEnhancedPainter& painter) override; virtual std::pair<QSizeF,QSizeF> getSize0(JKQTPEnhancedPainter& painter) override;
@ -922,6 +941,49 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPVerticalAxis: public JKQTPCoordinateAxis {
void drawAxisLabel1(JKQTPEnhancedPainter &painter, double left, double bottom, QSizeF labelMax, JKQTPCADrawMode drawMode); void drawAxisLabel1(JKQTPEnhancedPainter &painter, double left, double bottom, QSizeF labelMax, JKQTPCADrawMode drawMode);
/** \brief draw the axis label using \a painter for axis 2 at \c x= \a right and \c y= \a bottom. \a labelMax is the maximum Size of all tick labels */ /** \brief draw the axis label using \a painter for axis 2 at \c x= \a right and \c y= \a bottom. \a labelMax is the maximum Size of all tick labels */
void drawAxisLabel2(JKQTPEnhancedPainter &painter, double right, double bottom, QSizeF labelMax, JKQTPCADrawMode drawMode); void drawAxisLabel2(JKQTPEnhancedPainter &painter, double right, double bottom, QSizeF labelMax, JKQTPCADrawMode drawMode);
};
/*! \brief implements a vertical axis for use as primary, secondary, ... axis of a JKQTPBasePlotter,
* based on JKQTPCoordinateAxis (for most of documentation: see JKQTPCoordinateAxis).
\ingroup jkqtpbaseplotter_elements
The positioning of the different axis elements depends on the psition of the "other" axis (here x-axis),
i.e. the corresponding vertical axis:
\image html JKQTPVerticalAxisPositioning.png
*/
class JKQTPLOTTER_LIB_EXPORT JKQTPVerticalAxis: public JKQTPVerticalAxisBase {
Q_OBJECT
protected:
public:
/** \brief class constructor */
JKQTPVerticalAxis(JKQTBasePlotter* parent, JKQTPCoordinateAxisRef otherAxisRef=JKQTPPrimaryAxis);
/** copydoc JKQTPCoordinateAxis::getParentPlotWidth() */
virtual double getParentPlotWidth() const override;
/** copydoc JKQTPCoordinateAxis::getParentPlotOffset() */
virtual double getParentPlotOffset() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisWidth() */
virtual double getParentOtheraxisWidth() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisInverted() */
virtual bool getParentOtheraxisInverted() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisOffset() */
virtual double getParentOtheraxisOffset() const override;
/** copydoc JKQTPCoordinateAxis::parentOtherAxisX2P() */
virtual double parentOtherAxisX2P(double x) const override;
/** \copydoc otherAxisRef */
JKQTPCoordinateAxisRef getOtherAxisRef() const;
/** \brief returns the "other" axis, refernced by otherAxisRef */
const JKQTPCoordinateAxis* getOtherAxis() const;
protected:
/** \brief references the other axis fromm the JKQTPBasePLotter to use as "other" axis */
JKQTPCoordinateAxisRef otherAxisRef;
}; };
@ -944,7 +1006,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPVerticalAxis: public JKQTPCoordinateAxis {
If it is paired with another axis, the parameters of that axis have to be given explizitly in the constructor or with setters. If it is paired with another axis, the parameters of that axis have to be given explizitly in the constructor or with setters.
*/ */
class JKQTPLOTTER_LIB_EXPORT JKQTPVerticalIndependentAxis: public JKQTPVerticalAxis { class JKQTPLOTTER_LIB_EXPORT JKQTPVerticalIndependentAxis: public JKQTPVerticalAxisBase {
Q_OBJECT Q_OBJECT
protected: protected:
public: public:
@ -990,20 +1052,33 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPVerticalIndependentAxis: public JKQTPVerticalA
/*! \brief implements a horizontal axis, based on JKQTPCoordinateAxis (for most of documentation: see JKQTPCoordinateAxis). /*! \brief base class for horizontal axes, based on JKQTPCoordinateAxis (for most of documentation: see JKQTPCoordinateAxis).
\ingroup jkqtpbaseplotter_elements \ingroup jkqtpbaseplotter_elements
The positioning of the different axis elements depends on the psition of the "other" axis (here y-axis), The positioning of the different axis elements depends on the psition of the "other" axis (i.e. a vertical/y-axis),
i.e. the corresponding vertical axis: i.e. the corresponding vertical axis:
\image html JKQTPHorizontalAxisPositioning.png \image html JKQTPHorizontalAxisPositioning.png
But this "other>" axis is not defined here, but has to be defined in derived classes by immplementing the corresponding
pure virtual functions:
- getParentPlotWidth()
- getParentPlotOffset()
- getParentOtheraxisWidth()
- getParentOtheraxisInverted()
- getParentOtheraxisOffset()
- parentOtherAxisX2P()
.
\see JKQTPVerticalAxisBase
*/ */
class JKQTPLOTTER_LIB_EXPORT JKQTPHorizontalAxis: public JKQTPCoordinateAxis { class JKQTPLOTTER_LIB_EXPORT JKQTPHorizontalAxisBase: public JKQTPCoordinateAxis {
Q_OBJECT Q_OBJECT
protected: protected:
public: public:
/** \brief class constructor */ /** \brief class constructor */
JKQTPHorizontalAxis(JKQTBasePlotter* parent); JKQTPHorizontalAxisBase(JKQTBasePlotter* parent);
/** \brief returns the size of the bottom axis in pixels */ /** \brief returns the size of the bottom axis in pixels */
virtual QSizeF getSize1(JKQTPEnhancedPainter& painter) override; virtual QSizeF getSize1(JKQTPEnhancedPainter& painter) override;
@ -1012,25 +1087,12 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPHorizontalAxis: public JKQTPCoordinateAxis {
virtual QSizeF getSize2(JKQTPEnhancedPainter& painter) override; virtual QSizeF getSize2(JKQTPEnhancedPainter& painter) override;
/** copydoc JKQTPCoordinateAxis::drawAxes() */ /** copydoc JKQTPCoordinateAxis::drawAxes() */
virtual void drawAxes(JKQTPEnhancedPainter& painter) override; virtual void drawAxes(JKQTPEnhancedPainter& painter, int move1=0, int move2=0) override;
/** copydoc JKQTPCoordinateAxis::drawGrids() */ /** copydoc JKQTPCoordinateAxis::drawGrids() */
virtual void drawGrids(JKQTPEnhancedPainter& painter) override; virtual void drawGrids(JKQTPEnhancedPainter& painter) override;
/** copydoc JKQTPCoordinateAxis::getParentPlotWidth() */
virtual double getParentPlotWidth() const override;
/** copydoc JKQTPCoordinateAxis::getParentPlotOffset() */
virtual double getParentPlotOffset() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisWidth() */
virtual double getParentOtheraxisWidth() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisInverted() */
virtual bool getParentOtheraxisInverted() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisOffset() */
virtual double getParentOtheraxisOffset() const override;
/** copydoc JKQTPCoordinateAxis::parentOtherAxisX2P() */
virtual double parentOtherAxisX2P(double x) const override;
protected: protected:
/** copydoc JKQTPCoordinateAxis::getSize0() */ /** copydoc JKQTPCoordinateAxis::getSize0() */
virtual std::pair<QSizeF, QSizeF> getSize0(JKQTPEnhancedPainter& painter) override; virtual std::pair<QSizeF, QSizeF> getSize0(JKQTPEnhancedPainter& painter) override;
@ -1068,6 +1130,45 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPHorizontalAxis: public JKQTPCoordinateAxis {
}; };
/*! \brief implements a horizontal axis, based on JKQTPCoordinateAxis (for most of documentation: see JKQTPCoordinateAxis).
\ingroup jkqtpbaseplotter_elements
The positioning of the different axis elements depends on the psition of the "other" axis (here y-axis),
i.e. the corresponding vertical axis:
\image html JKQTPHorizontalAxisPositioning.png
*/
class JKQTPLOTTER_LIB_EXPORT JKQTPHorizontalAxis: public JKQTPHorizontalAxisBase {
Q_OBJECT
protected:
public:
/** \brief class constructor */
JKQTPHorizontalAxis(JKQTBasePlotter* parent, JKQTPCoordinateAxisRef otherAxisRef_=JKQTPPrimaryAxis);
/** copydoc JKQTPCoordinateAxis::getParentPlotWidth() */
virtual double getParentPlotWidth() const override;
/** copydoc JKQTPCoordinateAxis::getParentPlotOffset() */
virtual double getParentPlotOffset() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisWidth() */
virtual double getParentOtheraxisWidth() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisInverted() */
virtual bool getParentOtheraxisInverted() const override;
/** copydoc JKQTPCoordinateAxis::getParentOtheraxisOffset() */
virtual double getParentOtheraxisOffset() const override;
/** copydoc JKQTPCoordinateAxis::parentOtherAxisX2P() */
virtual double parentOtherAxisX2P(double x) const override;
/** \copydoc otherAxisRef */
JKQTPCoordinateAxisRef getOtherAxisRef() const;
/** \brief returns the "other" axis, refernced by otherAxisRef */
const JKQTPCoordinateAxis* getOtherAxis() const;
protected:
/** \brief references the other axis fromm the JKQTPBasePLotter to use as "other" axis */
JKQTPCoordinateAxisRef otherAxisRef;
};
/*! \brief implements a position-indipendent horizontal axis, based on JKQTPCoordinateAxis (for most of documentation: see JKQTPCoordinateAxis). /*! \brief implements a position-indipendent horizontal axis, based on JKQTPCoordinateAxis (for most of documentation: see JKQTPCoordinateAxis).
\ingroup jkqtpbaseplotter_elements \ingroup jkqtpbaseplotter_elements

View File

@ -34,7 +34,7 @@
#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz; #define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
JKQTPPlotElement::JKQTPPlotElement(JKQTBasePlotter* parent): JKQTPPlotElement::JKQTPPlotElement(JKQTBasePlotter* parent):
QObject(parent) QObject(parent), xAxisRef(JKQTPPrimaryAxis), yAxisRef(JKQTPPrimaryAxis)
{ {
title=""; title="";
visible=true; visible=true;
@ -225,18 +225,18 @@ double JKQTPPlotElement::hitTest(const QPointF & posSystem, QPointF* closestSpot
} }
double JKQTPPlotElement::transformX(double x) const { double JKQTPPlotElement::transformX(double x) const {
return parent->getXAxis()->x2p(x); return getXAxis()->x2p(x);
} }
double JKQTPPlotElement::transformY(double y) const { double JKQTPPlotElement::transformY(double y) const {
return parent->getYAxis()->x2p(y); return getYAxis()->x2p(y);
} }
QVector<double> JKQTPPlotElement::transformX(const QVector<double>& x) const { QVector<double> JKQTPPlotElement::transformX(const QVector<double>& x) const {
QVector<double> res; QVector<double> res;
res.resize(x.size()); res.resize(x.size());
for (int i=0; i<x.size(); i++) { for (int i=0; i<x.size(); i++) {
res[i]=parent->getXAxis()->x2p(x[i]); res[i]=getXAxis()->x2p(x[i]);
} }
return res; return res;
} }
@ -245,18 +245,38 @@ QVector<double> JKQTPPlotElement::transformY(const QVector<double>& y) const {
QVector<double> res; QVector<double> res;
res.resize(y.size()); res.resize(y.size());
for (int i=0; i<y.size(); i++) { for (int i=0; i<y.size(); i++) {
res[i]=parent->getYAxis()->x2p(y[i]); res[i]=getYAxis()->x2p(y[i]);
} }
return res; return res;
} }
void JKQTPPlotElement::setXAxis(JKQTPCoordinateAxisRef ref)
{
xAxisRef=ref;
}
void JKQTPPlotElement::setYAxis(JKQTPCoordinateAxisRef ref)
{
yAxisRef=ref;
}
JKQTPCoordinateAxisRef JKQTPPlotElement::getXAxisRef() const
{
return xAxisRef;
}
JKQTPCoordinateAxisRef JKQTPPlotElement::getYAxisRef() const
{
return yAxisRef;
}
double JKQTPPlotElement::backtransformX(double x) const { double JKQTPPlotElement::backtransformX(double x) const {
return parent->getXAxis()->p2x(x); return getXAxis()->p2x(x);
} }
double JKQTPPlotElement::backtransformY(double y) const { double JKQTPPlotElement::backtransformY(double y) const {
return parent->getYAxis()->p2x(y); return getYAxis()->p2x(y);
} }

View File

@ -208,16 +208,16 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPPlotElement: public QObject {
/** \brief tool routine that transforms an x-coordinate (plot coordinate --> pixels) for this plot element */ /** \brief tool routine that transforms an x-coordinate (plot coordinate --> pixels) for this plot element, uses the axis referenced in xAxisRef */
double transformX(double x) const; double transformX(double x) const;
/** \brief tool routine that transforms a y-coordinate (plot coordinate --> pixels) for this plot element */ /** \brief tool routine that transforms a y-coordinate (plot coordinate --> pixels) for this plot element, uses the axis referenced in yAxisRef */
double transformY(double y) const; double transformY(double y) const;
/** \brief tool routine that backtransforms an x-coordinate (pixels --> plot coordinate) for this plot element */ /** \brief tool routine that backtransforms an x-coordinate (pixels --> plot coordinate) for this plot element, uses the axis referenced in xAxisRef */
double backtransformX(double x) const; double backtransformX(double x) const;
/** \brief tool routine that backtransforms a y-coordinate (pixels --> plot coordinate) for this plot element */ /** \brief tool routine that backtransforms a y-coordinate (pixels --> plot coordinate) for this plot element, uses the axis referenced in yAxisRef */
double backtransformY(double y) const; double backtransformY(double y) const;
@ -254,6 +254,31 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPPlotElement: public QObject {
/** \brief transform all y-coordinates in a vector \a x */ /** \brief transform all y-coordinates in a vector \a x */
QVector<double> transformY(const QVector<double>& x) const; QVector<double> transformY(const QVector<double>& x) const;
/** \copydoc xAxisRef */
void setXAxis(JKQTPCoordinateAxisRef ref);
/** \copydoc xAxisRef */
JKQTPCoordinateAxisRef getXAxisRef() const;
/** \copydoc yAxisRef */
void setYAxis(JKQTPCoordinateAxisRef ref);
/** \copydoc yAxisRef */
JKQTPCoordinateAxisRef getYAxisRef() const;
/** \brief returns the actual x-Axis-object from the parent plotter, referenced in xAxisRef */
/** \brief returns the actual x-Axis-object from the parent plotter, referenced in xAxisRef */
inline const JKQTPCoordinateAxis* getXAxis() const {
return parent->getXAxis(xAxisRef);
}
/** \brief returns the actual y-Axis-object from the parent plotter, referenced in yAxisRef */
inline const JKQTPCoordinateAxis* getYAxis() const {
return parent->getYAxis(yAxisRef);
}
/** \brief set the coordinate axes to use for this plot element
*
* \see xAxisRef, yAxisRef, transformX(), transformY()
*/
void setAxes(JKQTPCoordinateAxisRef ref);
Q_PROPERTY(JKQTPCoordinateAxisRef xAxisRef READ getXAxisRef WRITE setXAxis)
Q_PROPERTY(JKQTPCoordinateAxisRef yAxisRef READ getYAxisRef WRITE setYAxis)
protected: protected:
@ -356,6 +381,11 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPPlotElement: public QObject {
bool highlighted; bool highlighted;
/** \brief internal storage for the used parent plot style */ /** \brief internal storage for the used parent plot style */
int parentPlotStyle; int parentPlotStyle;
/** \brief indicates which coordinate axis to use for coordinate transforms in x-direction */
JKQTPCoordinateAxisRef xAxisRef;
/** \brief indicates which coordinate axis to use for coordinate transforms in y-direction */
JKQTPCoordinateAxisRef yAxisRef;
/** \brief dataset with graph-points and associated data fro the function hitTest() /** \brief dataset with graph-points and associated data fro the function hitTest()

View File

@ -272,10 +272,10 @@ void JKQTPGraphErrorStyleMixin::intPlotXYErrorIndicators(JKQTPEnhancedPainter& p
if (!visX&&!visY) return; if (!visX&&!visY) return;
//std::cout<<" JKQTPGraphErrors::intPlotXYErrorIndicators(p, "<<parent<<", "<<xColumn<<", "<<yColumn<<", "<<xErrorColumn<<", "<<yErrorColumn<<", ...)\n"; //std::cout<<" JKQTPGraphErrors::intPlotXYErrorIndicators(p, "<<parent<<", "<<xColumn<<", "<<yColumn<<", "<<xErrorColumn<<", "<<yErrorColumn<<", ...)\n";
const double xmin=parentGraph->transformX(parent->getXAxis()->getMin()); const double xmin=parentGraph->transformX(parentGraph->getXAxis()->getMin());
const double xmax=parentGraph->transformX(parent->getXAxis()->getMax()); const double xmax=parentGraph->transformX(parentGraph->getXAxis()->getMax());
const double ymin=parentGraph->transformY(parent->getYAxis()->getMin()); const double ymin=parentGraph->transformY(parentGraph->getYAxis()->getMin());
const double ymax=parentGraph->transformY(parent->getYAxis()->getMax()); const double ymax=parentGraph->transformY(parentGraph->getYAxis()->getMax());
const QMarginsF clipMargins(50,50,50,50); const QMarginsF clipMargins(50,50,50,50);
const QRectF cliprect=QRectF(qMin(xmin,xmax),qMin(ymin,ymax),fabs(xmax-xmin),fabs(ymax-ymin))+clipMargins; const QRectF cliprect=QRectF(qMin(xmin,xmax),qMin(ymin,ymax),fabs(xmax-xmin),fabs(ymax-ymin))+clipMargins;

View File

@ -796,7 +796,7 @@ void JKQTPlotter::mouseMoveEvent ( QMouseEvent * event ) {
} else { } else {
zoomRect.translate(mouseDragRectXStartPixel-mouseDragRectXEndPixel, mouseDragRectYStartPixel-mouseDragRectYEndPixel); zoomRect.translate(mouseDragRectXStartPixel-mouseDragRectXEndPixel, mouseDragRectYStartPixel-mouseDragRectYEndPixel);
} }
setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top())); setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top()), true);
} }
} else { } else {
@ -900,7 +900,7 @@ void JKQTPlotter::mouseReleaseEvent ( QMouseEvent * event ){
plotter->correctXYRangeForAspectRatio(xmin,xmax,ymin,ymax); plotter->correctXYRangeForAspectRatio(xmin,xmax,ymin,ymax);
emit zoomChangedLocally(xmin, xmax, ymin, ymax, this); emit zoomChangedLocally(xmin, xmax, ymin, ymax, this);
plotter->setXY(xmin, xmax, ymin, ymax); plotter->setXY(xmin, xmax, ymin, ymax, true);
} else if (currentMouseDragAction.mode==jkqtpmdaPanPlotOnRelease) { } else if (currentMouseDragAction.mode==jkqtpmdaPanPlotOnRelease) {
QRectF zoomRect= QRectF(QPointF(plotter->x2p(getXAxis()->getMin()),plotter->y2p(getYAxis()->getMax())), QPointF(plotter->x2p(getXAxis()->getMax()),plotter->y2p(getYAxis()->getMin()))); QRectF zoomRect= QRectF(QPointF(plotter->x2p(getXAxis()->getMin()),plotter->y2p(getYAxis()->getMax())), QPointF(plotter->x2p(getXAxis()->getMax()),plotter->y2p(getYAxis()->getMin())));
if ( (mouseLastClickX/magnification<plotter->getInternalPlotBorderLeft()) || (mouseLastClickX/magnification>plotter->getPlotWidth()+plotter->getInternalPlotBorderLeft()) ) { if ( (mouseLastClickX/magnification<plotter->getInternalPlotBorderLeft()) || (mouseLastClickX/magnification>plotter->getPlotWidth()+plotter->getInternalPlotBorderLeft()) ) {
@ -910,7 +910,7 @@ void JKQTPlotter::mouseReleaseEvent ( QMouseEvent * event ){
} else { } else {
zoomRect.translate(mouseDragRectXStartPixel-mouseDragRectXEndPixel, mouseDragRectYStartPixel-mouseDragRectYEndPixel); zoomRect.translate(mouseDragRectXStartPixel-mouseDragRectXEndPixel, mouseDragRectYStartPixel-mouseDragRectYEndPixel);
} }
setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top())); setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top()), true);
} else if (currentMouseDragAction.mode==jkqtpmdaDrawRectangleForEvent) { } else if (currentMouseDragAction.mode==jkqtpmdaDrawRectangleForEvent) {
emit userRectangleFinished(x1, y1, x2-x1, y2-y1, event->modifiers()); emit userRectangleFinished(x1, y1, x2-x1, y2-y1, event->modifiers());
} else if (currentMouseDragAction.mode==jkqtpmdaDrawCircleForEvent) { } else if (currentMouseDragAction.mode==jkqtpmdaDrawCircleForEvent) {
@ -962,7 +962,7 @@ void JKQTPlotter::mouseDoubleClickEvent ( QMouseEvent * event ){
ymin=getYMin(); ymin=getYMin();
ymax=getYMax(); ymax=getYMax();
} }
plotter->setXY(xmin, xmax, ymin, ymax); plotter->setXY(xmin, xmax, ymin, ymax, true);
update(); update();
} else if (itAction.value()==JKQTPMouseDoubleClickActions::jkqtpdcaClickMovesViewport) { } else if (itAction.value()==JKQTPMouseDoubleClickActions::jkqtpdcaClickMovesViewport) {
QRectF zoomRect= QRectF(QPointF(plotter->x2p(getXAxis()->getMin()),plotter->y2p(getYAxis()->getMax())), QPointF(plotter->x2p(getXAxis()->getMax()),plotter->y2p(getYAxis()->getMin()))); QRectF zoomRect= QRectF(QPointF(plotter->x2p(getXAxis()->getMin()),plotter->y2p(getYAxis()->getMax())), QPointF(plotter->x2p(getXAxis()->getMax()),plotter->y2p(getYAxis()->getMin())));
@ -973,7 +973,7 @@ void JKQTPlotter::mouseDoubleClickEvent ( QMouseEvent * event ){
} else { } else {
zoomRect.moveCenter(QPointF(event->pos().x(), event->pos().y())); zoomRect.moveCenter(QPointF(event->pos().x(), event->pos().y()));
} }
setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top())); setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top()), true);
} }
} }
@ -1037,7 +1037,7 @@ void JKQTPlotter::wheelEvent ( QWheelEvent * event ) {
ymin=getYMin(); ymin=getYMin();
ymax=getYMax(); ymax=getYMax();
} }
plotter->setXY(xmin, xmax, ymin, ymax); plotter->setXY(xmin, xmax, ymin, ymax, true);
} else if (itAction.value()==JKQTPMouseWheelActions::jkqtpmwaPanByWheel) { } else if (itAction.value()==JKQTPMouseWheelActions::jkqtpmwaPanByWheel) {
//} else if (act==JKQTPMouseWheelActions::jkqtpmwaPanByWheel) { //} else if (act==JKQTPMouseWheelActions::jkqtpmwaPanByWheel) {
//qDebug()<<"wheelEvent("<<event->modifiers()<<"):PanByWheel"; //qDebug()<<"wheelEvent("<<event->modifiers()<<"):PanByWheel";
@ -1059,7 +1059,7 @@ void JKQTPlotter::wheelEvent ( QWheelEvent * event ) {
} else { } else {
zoomRect.translate(d.x(), d.y()); zoomRect.translate(d.x(), d.y());
} }
setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top())); setXY(plotter->p2x(zoomRect.left()), plotter->p2x(zoomRect.right()), plotter->p2y(zoomRect.bottom()), plotter->p2y(zoomRect.top()), true);
} }
} }

View File

@ -697,13 +697,13 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
int getMouseLastClickY() const; int getMouseLastClickY() const;
/** \brief returns the coordinate axis object for the x-axis \see JKQTBasePlotter::getXAxis() */ /** \brief returns the coordinate axis object for the x-axis \see JKQTBasePlotter::getXAxis() */
inline JKQTPHorizontalAxis* getXAxis() { return plotter->getXAxis(); } inline JKQTPHorizontalAxisBase* getXAxis(JKQTPCoordinateAxisRef axis=JKQTPPrimaryAxis) { return plotter->getXAxis(axis); }
/** \brief returns the coordinate axis object for the y-axis \see JKQTBasePlotter::getYAxis() */ /** \brief returns the coordinate axis object for the y-axis \see JKQTBasePlotter::getYAxis() */
inline JKQTPVerticalAxis* getYAxis() { return plotter->getYAxis(); } inline JKQTPVerticalAxisBase* getYAxis(JKQTPCoordinateAxisRef axis=JKQTPPrimaryAxis) { return plotter->getYAxis(axis); }
/** \brief returns the coordinate axis object for the x-axis as a const pointer \see JKQTBasePlotter::getXAxis() */ /** \brief returns the coordinate axis object for the x-axis as a const pointer \see JKQTBasePlotter::getXAxis() */
inline const JKQTPHorizontalAxis* getXAxis() const { return plotter->getXAxis(); } inline const JKQTPHorizontalAxisBase* getXAxis(JKQTPCoordinateAxisRef axis=JKQTPPrimaryAxis) const { return plotter->getXAxis(axis); }
/** \brief returns the coordinate axis object for the y-axis as a const pointer \see JKQTBasePlotter::getYAxis() */ /** \brief returns the coordinate axis object for the y-axis as a const pointer \see JKQTBasePlotter::getYAxis() */
inline const JKQTPVerticalAxis* getYAxis() const { return plotter->getYAxis(); } inline const JKQTPVerticalAxisBase* getYAxis(JKQTPCoordinateAxisRef axis=JKQTPPrimaryAxis) const { return plotter->getYAxis(axis); }
/** \brief returns the \a i -th graph (of type JKQTPPlotElement) in this plotter instance \see JKQTBasePlotter::getGraph() */ /** \brief returns the \a i -th graph (of type JKQTPPlotElement) in this plotter instance \see JKQTBasePlotter::getGraph() */
inline JKQTPPlotElement* getGraph(size_t i) { return plotter->getGraph(i); } inline JKQTPPlotElement* getGraph(size_t i) { return plotter->getGraph(i); }
@ -1185,6 +1185,10 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
* \param xmaxx absolute maximum of x-axis * \param xmaxx absolute maximum of x-axis
* \param yminn absolute minimum of y-axis * \param yminn absolute minimum of y-axis
* \param ymaxx absolute maximum of y-axis * \param ymaxx absolute maximum of y-axis
* \param affectsSecondaryAxes if \c true, the secondary axes are affectedtoo, by using a relative zooming scheme,
* i.e. if a major axis range shrinks by 50%, also the secondary ranges shrink by 50%
* [default: \c false]
*
* *
* \note You cannot expand the ranges outside the absolute ranges set e.g. by setAbsoluteXY()! * \note You cannot expand the ranges outside the absolute ranges set e.g. by setAbsoluteXY()!
* Also the range will be limited to possible values (e.g. to positive values if you use * Also the range will be limited to possible values (e.g. to positive values if you use
@ -1195,7 +1199,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
* *
* \see setX(), setX(), zoomToFit(), setAbsoluteXY(), JKQTBasePlotter::setXY() * \see setX(), setX(), zoomToFit(), setAbsoluteXY(), JKQTBasePlotter::setXY()
*/ */
inline void setXY(double xminn, double xmaxx, double yminn, double ymaxx) { plotter->setXY(xminn, xmaxx, yminn, ymaxx); } inline void setXY(double xminn, double xmaxx, double yminn, double ymaxx, bool affectsSecondaryAxes=false) { plotter->setXY(xminn, xmaxx, yminn, ymaxx, affectsSecondaryAxes); }
signals: signals:
/** \brief emitted whenever the mouse moves /** \brief emitted whenever the mouse moves
* *

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

BIN
screenshots/second_axis.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Some files were not shown because too many files have changed in this diff Show More