NEW: JKQTPXYGraphLabels which can draw a label next to each datapoint in the given x/y-dataset. The labels can be x-/y- or x&y-coordinates or custom, then defined by a user-supplied functor (+example \ref JKQTPlotterGraphLabels)
12
.gitignore
vendored
@ -164,3 +164,15 @@ Sicherungskopie_*
|
||||
/screenshots/datastore_statistics_dataonly_small.png
|
||||
/screenshots/datastore_statistics_hist_small.png
|
||||
/screenshots/datastore_statistics_kde_small.png
|
||||
/doc/images/JKQTPGLSimpleBoxAndLineVertical_small.png
|
||||
/doc/images/JKQTPGLSimpleBoxAndLine_small.png
|
||||
/doc/images/JKQTPGLSimpleVertical_small.png
|
||||
/doc/images/JKQTPGLSimple_small.png
|
||||
/doc/images/JKQTPGLabelAboveData_small.png
|
||||
/doc/images/JKQTPGLabelAwayFromXAxis_small.png
|
||||
/doc/images/JKQTPGLabelAwayFromYAxis_small.png
|
||||
/doc/images/JKQTPGLabelBelowData_small.png
|
||||
/doc/images/JKQTPGLabelLeftHandSide_small.png
|
||||
/doc/images/JKQTPGLabelRightHandSide_small.png
|
||||
/doc/images/JKQTPGLabelTowardsXAxis_small.png
|
||||
/doc/images/JKQTPGLabelTowardsYAxis_small.png
|
||||
|
@ -244,6 +244,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
|
||||
datastore_statistics_2d/datastore_statistics_2d
|
||||
multithreaded/multithreaded/--mdfile=${CMAKE_CURRENT_LIST_DIR}/../examples/multithreaded/README.md
|
||||
#"multithreaded_complex[multithreaded]/multithreaded_complex/--mdfile=${CMAKE_CURRENT_LIST_DIR}/../examples/multithreaded/README.md --complexlabel"
|
||||
graphlabels/graphlabels,graphlabels_hor
|
||||
)
|
||||
|
||||
|
||||
@ -271,6 +272,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
|
||||
symbols_and_errors/JKQTPXYLineErrorGraph_JKQTPErrorBars,JKQTPXYLineErrorGraph_JKQTPErrorLines,JKQTPXYLineErrorGraph_JKQTPErrorPolygons/--iteratefunctorsteps--iteratefunctorsteps_suppressinitial--smallscreenshotplot
|
||||
boxplot/JKQTPBoxplotVerticalGraph,JKQTPBoxplotHorizontalGraph/--iteratefunctorsteps--iteratefunctorsteps_suppressinitial--smallscreenshotplot
|
||||
second_axis/JKQTBasePlotter_addSecondaryYAxis,JKQTBasePlotter_addSecondaryXAxis
|
||||
graphlabels/JKQTPGLabelAwayFromXAxis,JKQTPGLabelAwayFromYAxis,JKQTPGLabelTowardsXAxis,JKQTPGLabelTowardsYAxis,JKQTPGLabelAboveData,JKQTPGLabelRightHandSide,JKQTPGLabelBelowData,JKQTPGLabelLeftHandSide,JKQTPGLSimple,JKQTPGLSimpleVertical,JKQTPGLSimpleBoxAndLine,JKQTPGLSimpleBoxAndLineVertical,JKQTPGLSimpleBoxAndLineONLYLABELS,JKQTPGLSimpleBoxAndLineONLYLABELSVertical/--iteratefunctorsteps--smallscreenshotplot
|
||||
)
|
||||
|
||||
|
||||
|
@ -113,6 +113,9 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
||||
<tr><td> \image html geo_coordinateaxis0_small.png
|
||||
<td> \subpage JKQTPlotterGeometricCoordinateAxis0
|
||||
<td> `JKQTPCoordinateAxisStyle::drawMode0`, `JKQTPGeoPolygon`, `JKQTPGeoEllipse`
|
||||
<tr><td> \image html JKQTPGLSimpleBoxAndLineONLYLABELS_small.png
|
||||
<td> \subpage JKQTPXYGraphLabels
|
||||
<td> `JKQTPXYGraphLabels`
|
||||
</table>
|
||||
|
||||
\subsection jkqtp_extut_keyaxesstyles Examples for Styling the Plot, Keys, Axes, ...
|
||||
|
@ -29,7 +29,10 @@ These classes are used by JKQTPlotterBase to output the plot.
|
||||
\defgroup jkqtplotter_basegraphserrors Mix-In Classes for Error Indicators
|
||||
\ingroup jkqtplotter_mixins
|
||||
|
||||
\defgroup jkqtplotter_basegraphs_stylemixins Mix-In Classes for Plot Styling
|
||||
\defgroup jkqtplotter_basegraphs_stylemixins Mix-In Classes for Styling General Graphs
|
||||
\ingroup jkqtplotter_mixins
|
||||
|
||||
\defgroup jkqtplotter_specialgraphs_stylemixins Mix-In Classes for Styling Specialized Graphs (Boxplots etz.)
|
||||
\ingroup jkqtplotter_mixins
|
||||
|
||||
|
||||
@ -116,6 +119,21 @@ This group assembles graphs that show their data with symbols and optionally wit
|
||||
</table>
|
||||
|
||||
|
||||
\defgroup jkqtplotter_graphlabels Labeling Datapoints
|
||||
\ingroup jkqtplotter_concretegraphs
|
||||
|
||||
This group assembles graphs that add (textual) labels to the datapoints in a plot:
|
||||
<table>
|
||||
<tr>
|
||||
<th> Screenshot
|
||||
<th> Classes
|
||||
<tr>
|
||||
<td>\image html JKQTPGLSimpleBoxAndLineONLYLABELS_small.png
|
||||
<td> JKQTPXYGraphLabels
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
\defgroup jkqtplotter_filledgraphs Filled Polygon/Area Graphs
|
||||
\ingroup jkqtplotter_concretegraphs
|
||||
|
||||
@ -243,6 +261,9 @@ Examples:
|
||||
<tr>
|
||||
<td>\image html geo_text_small.png
|
||||
<td> JKQTPGeoText
|
||||
<tr>
|
||||
<td>\image html JKQTPGLSimpleBoxAndLineONLYLABELS_small.png
|
||||
<td> JKQTPXYGraphLabels
|
||||
<tr>
|
||||
<td>\image html JKQTPHorizontalRange_small.png
|
||||
<td> JKQTPHorizontalRange, JKQTPVerticalRange
|
||||
|
@ -20,7 +20,6 @@ This page lists several todos and wishes for future version of JKQTPlotter
|
||||
<li>graphs: gant-chart as simplified vector field with (x,y1,y2) or (x1,x2,y), or (x,y,dx), (x,y,dy) ... different head/tail style</li>
|
||||
<li>graphs: matrix plots with boxes, labels, ...</li>
|
||||
<li>graphs: matrix plots with symbols: symbol-type, color, size should be parametric, cf. scatter plots</li>
|
||||
<li>graphs: text labels at positions/for graphs</li>
|
||||
<li>graphs: vector field graph (arrows), variant (x,y,dx,dy), (x,y,alpha,length), (x1,y1,x2,y2) ... different head/tail styles</li>
|
||||
<li>graphs: waterfall charts (see https://en.wikipedia.org/wiki/Waterfall_chart)</li>
|
||||
<li>graphs: parametrized variant of JKQTPSingleColumnSymbolsGraph (beeswarm plots etz.) where each symbol may have a color given by a second column</li>
|
||||
|
@ -127,6 +127,7 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
<li>NEW/REWORKED all functions in JKQTBasePlotter are re-entrant, i.e. different instances can be used from different threads in parallel (although there is some overhead due to shared caches between the threads!). This is demonstrated and discussed in \ref JKQTPlotterMultiThreaded . </li>
|
||||
<li>NEW: allow linear-gradient(), currentcolor, ... in brush definitions of style.ini-file ... and using it is cyberpunk and dark styles</li>
|
||||
<li>NEW: style simple_noaxes.ini</li>
|
||||
<li>NEW: JKQTPXYGraphLabels which can draw a label next to each datapoint in the given x/y-dataset. The labels can be x-/y- or x&y-coordinates or custom, then defined by a user-supplied functor (+example \ref JKQTPlotterGraphLabels)</li>
|
||||
</ul></li>
|
||||
|
||||
<li>JKQTMathText:<ul>
|
||||
|
BIN
doc/images/JKQTPGLSimple.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
doc/images/JKQTPGLSimpleBoxAndLine.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
doc/images/JKQTPGLSimpleBoxAndLineONLYLABELS.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
doc/images/JKQTPGLSimpleBoxAndLineONLYLABELSVertical.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
doc/images/JKQTPGLSimpleBoxAndLineONLYLABELSVertical_small.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
doc/images/JKQTPGLSimpleBoxAndLineONLYLABELS_small.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
BIN
doc/images/JKQTPGLSimpleBoxAndLineVertical.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
doc/images/JKQTPGLSimpleVertical.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
doc/images/JKQTPGLabelAboveData.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
doc/images/JKQTPGLabelAwayFromXAxis.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
doc/images/JKQTPGLabelAwayFromYAxis.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
doc/images/JKQTPGLabelBelowData.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
doc/images/JKQTPGLabelLeftHandSide.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
doc/images/JKQTPGLabelRightHandSide.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
doc/images/JKQTPGLabelTowardsXAxis.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
doc/images/JKQTPGLabelTowardsYAxis.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
doc/images/jkqtpxygraphlabels.png
Normal file
After Width: | Height: | Size: 12 KiB |
310
doc/images/jkqtpxygraphlabels.svg
Normal file
@ -0,0 +1,310 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="103.33672mm"
|
||||
height="28.842316mm"
|
||||
id="svg3219"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
|
||||
sodipodi:docname="jkqtpxygraphlabels.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596"
|
||||
version="1.1"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs3221">
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Arrow1Send"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Send"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path5531" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="marker5794"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Sstart"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(0.3,0,0,0.3,-0.69,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:0.625;stroke-linejoin:round"
|
||||
id="path5792" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Arrow2Sstart"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Sstart"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(0.3,0,0,0.3,-0.69,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:0.625;stroke-linejoin:round"
|
||||
id="path5546" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Arrow1Mend"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
id="path5525" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3942"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3939"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(1.1,0,0,1.1,1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3921"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : -452.24953 : 1"
|
||||
inkscape:vp_y="0 : 1066.6667 : 0"
|
||||
inkscape:vp_z="793.70078 : -452.24953 : 1"
|
||||
inkscape:persp3d-origin="396.85039 : -639.33614 : 1"
|
||||
id="perspective3227" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.2314489"
|
||||
inkscape:cx="252.54803"
|
||||
inkscape:cy="-73.084639"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="2240"
|
||||
inkscape:window-height="1329"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata3224">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-21.442405,-12.040758)">
|
||||
<g
|
||||
id="g5366"
|
||||
style="fill:#cccccc"
|
||||
transform="matrix(1.4976605,0,0,1.4976605,-324.58377,-31.251985)"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596">
|
||||
<rect
|
||||
style="fill:#cccccc;stroke:#000000;stroke-width:1.00353;stroke-linejoin:round;stroke-miterlimit:10"
|
||||
id="rect3209"
|
||||
width="61.61441"
|
||||
height="27.73167"
|
||||
x="298.22592"
|
||||
y="42.927017" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:22.4671px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.561677"
|
||||
x="303.16748"
|
||||
y="65.748497"
|
||||
id="text4093"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4091"
|
||||
x="303.16748"
|
||||
y="65.748497"
|
||||
style="fill:#000000;stroke-width:0.561677">label</tspan></text>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:16.6981px;line-height:0%;font-family:'Bitstream Vera Sans';text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1.39151px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="138.41815"
|
||||
y="116.77113"
|
||||
id="text6295"
|
||||
transform="scale(1.0899925,0.91743751)"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6297"
|
||||
x="138.41815"
|
||||
y="116.77113"
|
||||
style="font-size:30.0009px;line-height:1.25;fill:#0000ff;stroke:none;stroke-width:1.39151px">+</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:23.4608px;line-height:0%;font-family:'Bitstream Vera Sans';text-align:center;text-anchor:middle;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1.95506px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="176.46564"
|
||||
y="115.88972"
|
||||
id="text6299"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596"><tspan
|
||||
sodipodi:role="line"
|
||||
x="176.46564"
|
||||
y="115.88972"
|
||||
style="font-size:21.5057px;line-height:1.25;fill:#0000ff;stroke-width:1.95506px"
|
||||
id="tspan6303">(x, y)</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#ff0000;stroke-width:1.46956px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Sstart);marker-end:url(#Arrow1Send)"
|
||||
d="M 145.35723,95.464988 V 77.489556"
|
||||
id="path5401"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:21.9208px;line-height:1.25;font-family:sans-serif;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.548019"
|
||||
x="19.316088"
|
||||
y="96.100845"
|
||||
id="text6890"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6888"
|
||||
x="19.316088"
|
||||
y="96.100845"
|
||||
style="stroke-width:0.548019">LabelOffset</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.645401px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Sstart);marker-end:url(#Arrow1Send)"
|
||||
d="M 161.49675,40.391734 V 35.019722"
|
||||
id="path8100"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:21.9208px;line-height:1.25;font-family:sans-serif;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.548019"
|
||||
x="98.085098"
|
||||
y="28.700565"
|
||||
id="text8104"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan8102"
|
||||
x="98.085098"
|
||||
y="28.700565"
|
||||
style="stroke-width:0.548019">LabelYPadding</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.99328px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Sstart);marker-end:url(#Arrow1Send)"
|
||||
d="m 212.15832,51.099655 h -8.26759"
|
||||
id="path11778"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:21.9208px;line-height:1.25;font-family:sans-serif;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.548019"
|
||||
x="217.15215"
|
||||
y="58.137436"
|
||||
id="text11782"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan11780"
|
||||
x="217.15215"
|
||||
y="58.137436"
|
||||
style="stroke-width:0.548019">LabelXPadding</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.99328px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Send)"
|
||||
d="m 203.23396,70.791905 h 8.26759"
|
||||
id="path13399"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596" />
|
||||
<path
|
||||
style="fill:none;stroke:#ff0000;stroke-width:0.99328px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Send)"
|
||||
d="m 224.74512,70.791905 h -8.26759"
|
||||
id="path13401"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:21.9208px;line-height:1.25;font-family:sans-serif;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.548019"
|
||||
x="226.49074"
|
||||
y="81.483917"
|
||||
id="text13419"
|
||||
inkscape:export-filename="C:\Jan\Programmieren\JKQtPlotter\doc\images\jkqtpxygraphlabels.png"
|
||||
inkscape:export-xdpi="61.449596"
|
||||
inkscape:export-ydpi="61.449596"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan13417"
|
||||
x="226.49074"
|
||||
y="81.483917"
|
||||
style="stroke-width:0.548019">LabelBorderWidth</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 13 KiB |
@ -74,6 +74,7 @@ if (JKQtPlotter_BUILD_LIB_JKQTPLOTTER)
|
||||
add_subdirectory(geo_simple)
|
||||
add_subdirectory(geo_coordinateaxis0)
|
||||
add_subdirectory(geometric)
|
||||
add_subdirectory(graphlabels)
|
||||
add_subdirectory(imageplot)
|
||||
add_subdirectory(imageplot_cimg)
|
||||
add_subdirectory(imageplot_modifier)
|
||||
|
25
examples/graphlabels/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
|
||||
set(EXAMPLE_NAME graphlabels)
|
||||
set(EXENAME jkqtptest_${EXAMPLE_NAME})
|
||||
|
||||
message( STATUS ".. Building Example ${EXAMPLE_NAME}" )
|
||||
|
||||
|
||||
|
||||
add_executable(${EXENAME} WIN32 ${EXAMPLE_NAME}.cpp)
|
||||
target_link_libraries(${EXENAME} JKQTPExampleToolsLib)
|
||||
target_include_directories(${EXENAME} PRIVATE ../../lib)
|
||||
target_link_libraries(${EXENAME} ${jkqtplotter_namespace}JKQTPlotter${jkqtplotter_LIBNAME_VERSION_PART})
|
||||
|
||||
# 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})
|
16
examples/graphlabels/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Example (JKQTPlotter): Simple Graph Labels Example {#JKQTPlotterGraphLabels}
|
||||
This project (see [`graphlabels`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/graphlabels) demonstrates the use of JKQTPXYGraphLabels to add labels to the datapoints of a graph.
|
||||
|
||||
The source code of the main application is (see [`graphlabels.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/graphlabels/graphlabels.cpp):
|
||||
```.cpp
|
||||
```
|
||||
|
||||
|
||||
The result looks like this:
|
||||
|
||||
![graphlabels](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/graphlabels.png)
|
||||
|
||||
or this:
|
||||
|
||||
![graphlabels_hor](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/graphlabels_hor.png)
|
||||
|
144
examples/graphlabels/graphlabels.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
/** \example graphlabels.cpp
|
||||
* Shows how to draw datapoint labels using JKQTPXYGraphLabels
|
||||
*
|
||||
* \ref JKQTPlotterGraphLabels
|
||||
*/
|
||||
|
||||
#include "jkqtpexampleapplication.h"
|
||||
#include <QApplication>
|
||||
#include "jkqtplotter/jkqtplotter.h"
|
||||
#include "jkqtplotter/graphs/jkqtpscatter.h"
|
||||
#include "jkqtplotter/graphs/jkqtpbarchart.h"
|
||||
#include "jkqtplotter/graphs/jkqtpgraphlabels.h"
|
||||
#include "jkqtpexampleapplication.h"
|
||||
|
||||
#define Ndata 6
|
||||
|
||||
|
||||
template <class TCHART>
|
||||
std::pair<TCHART*, JKQTPXYGraphLabels*> doExample(JKQTPlotter& plot, const QString& title, JKQTPGraphLabelPosition labPos)
|
||||
{
|
||||
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
|
||||
plot.getPlotter()->setUseAntiAliasingForGraphs(true); // nicer (but slower) plotting
|
||||
plot.getPlotter()->setUseAntiAliasingForSystem(true); // nicer (but slower) plotting
|
||||
plot.getPlotter()->setUseAntiAliasingForText(true); // nicer (but slower) text rendering
|
||||
JKQTPDatastore* ds=plot.getDatastore();
|
||||
|
||||
|
||||
|
||||
// 2. make up some arbitrary data to be used for plotting
|
||||
const size_t columnX=ds->addLinearColumn(Ndata, -1,1,"x");
|
||||
const size_t columnY=ds->addCalculatedColumnFromColumn(columnX, [](double x) { return jkqtp_roundToDigits(-sin(x*3.0),2);}, "data");
|
||||
|
||||
|
||||
// 3. create barchart and line-chart to display the data:
|
||||
TCHART* graph1=new TCHART(&plot);
|
||||
graph1->setBarPositionColumn(columnX);
|
||||
graph1->setBarHeightColumn(columnY);
|
||||
graph1->setTitle(QObject::tr("dataset: bars"));
|
||||
graph1->setColor(QColorWithAlphaF(graph1->getFillColor(),0.25));
|
||||
JKQTPXYLineGraph* graph2=new JKQTPXYLineGraph(&plot);
|
||||
if (typeid(TCHART)==typeid(JKQTPBarVerticalGraph)) {
|
||||
graph2->setXColumn(columnX);
|
||||
graph2->setYColumn(columnY);
|
||||
} else {
|
||||
graph2->setXColumn(columnY);
|
||||
graph2->setYColumn(columnX);
|
||||
}
|
||||
graph2->setTitle(QObject::tr("dataset: lines"));
|
||||
graph2->setColor(QColorWithAlphaF(graph2->getLineColor(),0.5));
|
||||
|
||||
// 4.1. create barchart to display the data:
|
||||
JKQTPXYGraphLabels* graphLabels=new JKQTPXYGraphLabels((typeid(TCHART)==typeid(JKQTPBarVerticalGraph)) ? JKQTPXYGraphLabels::YValueLabel : JKQTPXYGraphLabels::XValueLabel, &plot);
|
||||
graphLabels->setXColumn(graph1->getXColumn());
|
||||
graphLabels->setYColumn(graph1->getYColumn());
|
||||
|
||||
// 4.2. set position of labels and some styling options
|
||||
graphLabels->setLabelPosition(labPos);
|
||||
graphLabels->setTextFontSize(14);
|
||||
|
||||
// 5. add the graphs to the plot, so it is actually displayed
|
||||
plot.addGraph(graph1);
|
||||
plot.addGraph(graph2);
|
||||
plot.addGraph(graphLabels);
|
||||
|
||||
// 6. scale the plot so the graph is contained
|
||||
plot.setXY(-1.5,1.5,-1.5,1.5);
|
||||
|
||||
// 7.modify the plot style a bit
|
||||
plot.getXAxis()->setDrawMode1(JKQTPCADMLine);
|
||||
plot.getXAxis()->setDrawMode2(JKQTPCADMLine);
|
||||
plot.getYAxis()->setDrawMode1(JKQTPCADMLine);
|
||||
plot.getYAxis()->setDrawMode2(JKQTPCADMLine);
|
||||
|
||||
// show plotter and make it a decent size
|
||||
plot.setWindowTitle(title);
|
||||
plot.show();
|
||||
plot.resize(400/plot.devicePixelRatioF(),250/plot.devicePixelRatioF());
|
||||
|
||||
return {graph1, graphLabels};
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
JKQTPAppSettingController highDPIController(argc,argv);
|
||||
JKQTPExampleApplication app(argc, argv);
|
||||
|
||||
JKQTPlotter plotV;
|
||||
auto gV=doExample<JKQTPBarVerticalGraph>(plotV, "1: JKQTPXYGraphLabels+JKQTPBarVerticalGraph", JKQTPGLabelAwayFromXAxis);
|
||||
JKQTPlotter plotH;
|
||||
auto gH=doExample<JKQTPBarHorizontalGraph>(plotH, "2: JKQTPXYGraphLabels+JKQTPBarHorizontalGraph", JKQTPGLabelAwayFromYAxis);
|
||||
|
||||
app.addExportStepFunctor([&](){
|
||||
gV.second->setLabelPosition(JKQTPGLabelTowardsXAxis);
|
||||
gH.second->setLabelPosition(JKQTPGLabelTowardsYAxis);
|
||||
plotV.redrawPlot();
|
||||
plotH.redrawPlot();
|
||||
});
|
||||
|
||||
app.addExportStepFunctor([&](){
|
||||
gV.second->setLabelPosition(JKQTPGLabelAboveData);
|
||||
gH.second->setLabelPosition(JKQTPGLabelRightHandSide);
|
||||
plotV.redrawPlot();
|
||||
plotH.redrawPlot();
|
||||
});
|
||||
|
||||
app.addExportStepFunctor([&](){
|
||||
gV.second->setLabelPosition(JKQTPGLabelBelowData);
|
||||
gH.second->setLabelPosition(JKQTPGLabelLeftHandSide);
|
||||
plotV.redrawPlot();
|
||||
plotH.redrawPlot();
|
||||
});
|
||||
app.addExportStepFunctor([&](){
|
||||
gV.second->setLabelPosition(JKQTPGLabelAwayFromXAxis);
|
||||
gV.second->setLabelBoxType(JKQTPGLSimpleBox);
|
||||
gV.second->setDrawLabelBoxFrame(true);
|
||||
gH.second->setLabelPosition(JKQTPGLabelAwayFromYAxis);
|
||||
gH.second->setLabelBoxType(JKQTPGLSimpleBox);
|
||||
gH.second->setDrawLabelBoxFrame(true);
|
||||
plotV.redrawPlot();
|
||||
plotH.redrawPlot();
|
||||
});
|
||||
app.addExportStepFunctor([&](){
|
||||
gV.second->setLabelPosition(JKQTPGLabelAwayFromXAxis);
|
||||
gV.second->setLabelBoxType(JKQTPGLSimpleBoxAndLine);
|
||||
gV.second->setDrawLabelBoxFrame(true);
|
||||
gH.second->setLabelPosition(JKQTPGLabelAwayFromYAxis);
|
||||
gH.second->setLabelBoxType(JKQTPGLSimpleBoxAndLine);
|
||||
gH.second->setDrawLabelBoxFrame(true);
|
||||
plotV.redrawPlot();
|
||||
plotH.redrawPlot();
|
||||
});
|
||||
app.addExportStepFunctor([&](){
|
||||
//plotV.getPlotter()->setOnlyGraphVisible(plotV.getPlotter()->indexOfGraph(gV.second));
|
||||
//plotH.getPlotter()->setOnlyGraphVisible(plotH.getPlotter()->indexOfGraph(gH.second));
|
||||
gV.first->setVisible(false);
|
||||
gH.first->setVisible(false);
|
||||
|
||||
plotV.redrawPlot();
|
||||
plotH.redrawPlot();
|
||||
});
|
||||
|
||||
return app.exec();
|
||||
}
|
@ -97,10 +97,10 @@ This test results in the following numbers (on my AMD Ryzen5 8/16-core laptop):
|
||||
<b>VERSION:</b> 5.0.0
|
||||
<b>BUILD MODE:</b> Release
|
||||
|
||||
<u><b>SERIAL RESULTS:</b></u><br/>runtime, overall = 11199.2ms<br/>single runtimes = (466.6 +/- 1681.5) ms<br/>speedup = 1.00x<br/>threads / available = 1 / 16<br/><br/><br/>
|
||||
<u><b>SERIAL RESULTS:</b></u><br/>runtime, overall = 12353.5ms<br/>single runtimes = (514.6 +/- 1737.1) ms<br/>speedup = 1.00x<br/>threads / available = 1 / 16<br/><br/><br/>
|
||||
|
||||
<u><b>PARALLEL RESULTS:</b></u><br/>
|
||||
runtime, overall = 2157.8ms<br/>single runtimes = (596.8 +/- 85.1) ms<br/>speedup = 6.64x<br/>threads / available = 8 / 16<br/>batch runs = 3<br/><br/><b>speedup vs. serial = 5.2x</b>
|
||||
runtime, overall = 3440.1ms<br/>single runtimes = (739.1 +/- 91.8) ms<br/>speedup = 5.16x<br/>threads / available = 8 / 16<br/>batch runs = 3<br/><br/><b>speedup vs. serial = 3.6x</b>
|
||||
|
||||
[comment]:RESULTS_END
|
||||
|
||||
|
@ -57,6 +57,7 @@ isEmpty(JKQTP_PLOTTER_PRI_INCLUDED) {
|
||||
$$PWD/jkqtplotter/graphs/jkqtpbarchart.h \
|
||||
$$PWD/jkqtplotter/graphs/jkqtpevaluatedparametriccurve.h \
|
||||
$$PWD/jkqtplotter/graphs/jkqtplines.h \
|
||||
$$PWD/jkqtplotter/graphs/jkqtpgraphlabels.h \
|
||||
$$PWD/jkqtplotter/gui/jkqtpcomboboxes.h \
|
||||
$$PWD/jkqtplotter/gui/jkqtpenhancedspinboxes.h \
|
||||
$$PWD/jkqtplotter/gui/jkqtpenhancedtableview.h \
|
||||
@ -111,6 +112,7 @@ isEmpty(JKQTP_PLOTTER_PRI_INCLUDED) {
|
||||
$$PWD/jkqtplotter/graphs/jkqtpbarchart.cpp \
|
||||
$$PWD/jkqtplotter/graphs/jkqtpevaluatedparametriccurve.cpp \
|
||||
$$PWD/jkqtplotter/graphs/jkqtplines.cpp \
|
||||
$$PWD/jkqtplotter/graphs/jkqtpgraphlabels.cpp \
|
||||
$$PWD/jkqtplotter/gui/jkqtpcomboboxes.cpp \
|
||||
$$PWD/jkqtplotter/gui/jkqtpenhancedspinboxes.cpp \
|
||||
$$PWD/jkqtplotter/gui/jkqtpenhancedtableview.cpp \
|
||||
|
@ -31,6 +31,8 @@ target_sources(${lib_name} PRIVATE
|
||||
jkqtpstatisticsadaptors.cpp
|
||||
jkqtpevaluatedparametriccurve.cpp
|
||||
jkqtplines.cpp
|
||||
jkqtpgraphlabelstylemixin.cpp
|
||||
jkqtpgraphlabels.cpp
|
||||
)
|
||||
# ... and add headers
|
||||
target_sources(${lib_name} PUBLIC FILE_SET HEADERS TYPE HEADERS
|
||||
@ -64,4 +66,6 @@ target_sources(${lib_name} PUBLIC FILE_SET HEADERS TYPE HEADERS
|
||||
jkqtpbarchart.h
|
||||
jkqtpevaluatedparametriccurve.h
|
||||
jkqtplines.h
|
||||
)
|
||||
jkqtpgraphlabelstylemixin.h
|
||||
jkqtpgraphlabels.h
|
||||
)
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
|
||||
/*! \brief Styling Mix-In for Boxplots
|
||||
\ingroup jkqtplotter_basegraphs_stylemixins
|
||||
\ingroup jkqtplotter_specialgraphs_stylemixins
|
||||
|
||||
|
||||
\image html plot_boxplothorizontalelement.png
|
||||
|
216
lib/jkqtplotter/graphs/jkqtpgraphlabels.cpp
Normal file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
|
||||
|
||||
|
||||
|
||||
This software is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||
the Free Software Foundation, either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License (LGPL) for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "jkqtplotter/graphs/jkqtpgraphlabels.h"
|
||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||
#include "jkqtplotter/jkqtplotter.h"
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
#include "jkqtcommon/jkqtpdrawingtools.h"
|
||||
#include "jkqtplotter/jkqtptools.h"
|
||||
|
||||
#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
||||
|
||||
|
||||
|
||||
JKQTPXYGraphLabels::JKQTPXYGraphLabels(LabelContentsDefaultType lt, JKQTPlotter* parent):
|
||||
JKQTPXYGraphLabels(lt, parent->getPlotter())
|
||||
{
|
||||
}
|
||||
|
||||
JKQTPXYGraphLabels::JKQTPXYGraphLabels(const LabelGenerator &lgen, JKQTBasePlotter *parent):
|
||||
JKQTPXYGraphLabels(YValueLabel, parent)
|
||||
{
|
||||
setCustomLabelGenerator(lgen);
|
||||
}
|
||||
|
||||
JKQTPXYGraphLabels::JKQTPXYGraphLabels(const LabelGenerator &lgen, JKQTPlotter *parent):
|
||||
JKQTPXYGraphLabels(lgen, parent->getPlotter())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JKQTPXYGraphLabels::JKQTPXYGraphLabels(LabelContentsDefaultType lt, JKQTBasePlotter* parent):
|
||||
JKQTPXYGraph(parent), JKQTPGraphValueLabelStyleMixin(parent)
|
||||
{
|
||||
sortData=JKQTPXYGraph::Unsorted;
|
||||
|
||||
initValueLabelStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Default);
|
||||
|
||||
switch(lt) {
|
||||
case XValueLabel:
|
||||
setDefaultXLabelGenerator();
|
||||
break;
|
||||
case YValueLabel:
|
||||
setDefaultYLabelGenerator();
|
||||
break;
|
||||
case XYValueLabel:
|
||||
setDefaultXYLabelGenerator();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JKQTPXYGraphLabels::draw(JKQTPEnhancedPainter& painter) {
|
||||
#ifdef JKQTBP_AUTOTIMER
|
||||
JKQTPAutoOutputTimer jkaaot("JKQTPXYGraphLabels::draw");
|
||||
#endif
|
||||
if (parent==nullptr) return;
|
||||
const JKQTPDatastore* datastore=parent->getDatastore();
|
||||
if (datastore==nullptr) return;
|
||||
|
||||
drawErrorsBefore(painter);
|
||||
{
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
|
||||
int imax=0;
|
||||
int imin=0;
|
||||
if (getIndexRange(imin, imax)) {
|
||||
for (int iii=imin; iii<imax; iii++) {
|
||||
const int i=qBound(imin, getDataIndex(iii), imax);
|
||||
const double xv=datastore->get(static_cast<size_t>(xColumn),static_cast<size_t>(i));
|
||||
const double yv=datastore->get(static_cast<size_t>(yColumn),static_cast<size_t>(i));
|
||||
const double x=transformX(xv);
|
||||
const double y=transformY(yv);
|
||||
if (JKQTPIsOKFloat(xv) && JKQTPIsOKFloat(yv) && JKQTPIsOKFloat(x) && JKQTPIsOKFloat(y)) {
|
||||
const QString label=generateLabel(xv,yv,iii);
|
||||
drawLabel(painter, QPointF(x,y), QPointF(xv,yv), label, parent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
drawErrorsAfter(painter);
|
||||
}
|
||||
|
||||
void JKQTPXYGraphLabels::drawKeyMarker(JKQTPEnhancedPainter& painter, const QRectF& rect) {
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
painter.setFont(QFont(QGuiApplication::font().family(), getTextFontSize()));
|
||||
painter.setPen(getTextColor());
|
||||
painter.drawText(rect,Qt::AlignHCenter|Qt::AlignVCenter, "12");
|
||||
}
|
||||
|
||||
QColor JKQTPXYGraphLabels::getKeyLabelColor() const {
|
||||
return getTextColor();
|
||||
}
|
||||
|
||||
void JKQTPXYGraphLabels::setColor(QColor c, bool setTextColor_, bool setFrameColor_)
|
||||
{
|
||||
if (setTextColor_) setTextColor(c);
|
||||
if (setFrameColor_) setLineColor(c);
|
||||
}
|
||||
|
||||
void JKQTPXYGraphLabels::setCustomLabelGenerator(const LabelGenerator &labgen)
|
||||
{
|
||||
m_labelGenerator=labgen;
|
||||
}
|
||||
|
||||
void JKQTPXYGraphLabels::setDefaultXLabelGenerator()
|
||||
{
|
||||
m_labelGenerator=std::bind(std::mem_fn(&JKQTPXYGraphLabels::generateDefaultXLabel), this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
}
|
||||
|
||||
void JKQTPXYGraphLabels::setDefaultYLabelGenerator()
|
||||
{
|
||||
m_labelGenerator=std::bind(std::mem_fn(&JKQTPXYGraphLabels::generateDefaultYLabel), this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
}
|
||||
|
||||
void JKQTPXYGraphLabels::setDefaultXYLabelGenerator()
|
||||
{
|
||||
m_labelGenerator=std::bind(std::mem_fn(&JKQTPXYGraphLabels::generateDefaultXYLabel), this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
}
|
||||
|
||||
|
||||
bool JKQTPXYGraphLabels::getXMinMax(double &minx, double &maxx, double &smallestGreaterZero)
|
||||
{
|
||||
const bool baseResult=JKQTPXYGraph::getXMinMax(minx,maxx,smallestGreaterZero);
|
||||
if (baseResult) {
|
||||
/*
|
||||
// this does not work, as it depends on the widget size, when called!!!
|
||||
qDebug()<<"JKQTPXYGraphLabels::getXMinMax():";
|
||||
qDebug()<<" minx="<<minx<<", maxx="<<maxx;
|
||||
const double delta=(isLabelPositioningGrowingInY())? 0.0: parent->pt2px(getLabelOffset()+getLabelXPadding()+getTextFontSize()*2.0,96.0);
|
||||
const double mi_x=transformX(minx);
|
||||
const double ma_x=transformX(maxx);
|
||||
qDebug()<<" mi_x="<<mi_x<<", ma_x="<<ma_x<<", delta="<<delta;
|
||||
const double new_mi_x=backtransformX(qMin(mi_x,ma_x)-delta);
|
||||
const double new_ma_x=backtransformX(qMax(mi_x,ma_x)+delta);
|
||||
qDebug()<<" new_mi_x="<<new_mi_x<<", new_ma_x="<<new_ma_x;
|
||||
minx=qMin(minx,qMin(new_mi_x,new_ma_x));
|
||||
maxx=qMax(maxx,qMax(new_mi_x,new_ma_x));
|
||||
qDebug()<<"->minx="<<minx<<", maxx="<<maxx;*/
|
||||
|
||||
// ... so if required, we just extend the range by ~15%
|
||||
if (!isLabelPositioningGrowingInX()) {
|
||||
const double mi_x=transformY(minx);
|
||||
const double ma_x=transformY(maxx);
|
||||
const double delta=fabs(ma_x-mi_x)*0.15/2.0;
|
||||
const double new_mi=backtransformY(qMax(mi_x,ma_x)+delta);
|
||||
const double new_ma=backtransformY(qMin(mi_x,ma_x)-delta);
|
||||
minx=qMin(minx,qMin(new_mi,new_ma));
|
||||
maxx=qMax(maxx,qMax(new_mi,new_ma));
|
||||
}
|
||||
}
|
||||
return baseResult;
|
||||
}
|
||||
|
||||
bool JKQTPXYGraphLabels::getYMinMax(double &miny, double &maxy, double &smallestGreaterZero)
|
||||
{
|
||||
const bool baseResult=JKQTPXYGraph::getYMinMax(miny,maxy,smallestGreaterZero);
|
||||
if (baseResult) {
|
||||
/*
|
||||
qDebug()<<"JKQTPXYGraphLabels::getXMinMax():";
|
||||
qDebug()<<" minx="<<miny<<", maxx="<<maxy;
|
||||
const double delta=(!isLabelPositioningGrowingInY())?0.0: parent->pt2px(getLabelOffset()+getLabelYPadding()*2.0+getTextFontSize(),96.0);
|
||||
const double mi_y=transformY(miny);
|
||||
const double ma_y=transformY(maxy);
|
||||
qDebug()<<" mi_x="<<mi_y<<", ma_x="<<ma_y<<", delta="<<delta;
|
||||
const double new_mi_y=backtransformY(qMin(mi_y,ma_y)-delta);
|
||||
const double new_ma_y=backtransformY(qMax(mi_y,ma_y)+delta);
|
||||
qDebug()<<" new_mi_x="<<new_mi_y<<", new_ma_x="<<new_ma_y;
|
||||
miny=qMin(miny,qMin(new_mi_y,new_ma_y));
|
||||
maxy=qMax(maxy,qMax(new_mi_y,new_ma_y));
|
||||
qDebug()<<"->minx="<<miny<<", maxx="<<maxy;
|
||||
*/
|
||||
// ... so if required, we just extend the range by ~10%
|
||||
if (isLabelPositioningGrowingInY()) {
|
||||
const double mi_y=transformY(miny);
|
||||
const double ma_y=transformY(maxy);
|
||||
const double delta=fabs(ma_y-mi_y)*0.15/2.0;
|
||||
const double new_mi=backtransformY(qMax(mi_y,ma_y)+delta);
|
||||
const double new_ma=backtransformY(qMin(mi_y,ma_y)-delta);
|
||||
miny=qMin(miny,qMin(new_mi,new_ma));
|
||||
maxy=qMax(maxy,qMax(new_mi,new_ma));
|
||||
}
|
||||
|
||||
}
|
||||
return baseResult;
|
||||
}
|
||||
|
||||
QString JKQTPXYGraphLabels::generateLabel(double x, double y, int index) const
|
||||
{
|
||||
if (m_labelGenerator) return m_labelGenerator(x,y,index);
|
||||
else {
|
||||
qWarning()<<"no label generator functor set in JKQTPXYGraphLabels";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
168
lib/jkqtplotter/graphs/jkqtpgraphlabels.h
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
Copyright (c) 2008-2024 Jan W. Krieger (<jan@jkrieger.de>)
|
||||
|
||||
|
||||
|
||||
This software is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||
the Free Software Foundation, either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License (LGPL) for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef jkqtpgraphlabels_H
|
||||
#define jkqtpgraphlabels_H
|
||||
|
||||
|
||||
#include <QString>
|
||||
#include <QPainter>
|
||||
#include <QPair>
|
||||
#include <functional>
|
||||
#include "jkqtplotter/jkqtptools.h"
|
||||
#include "jkqtplotter/jkqtplotter_imexport.h"
|
||||
#include "jkqtplotter/jkqtpgraphsbase.h"
|
||||
#include "jkqtplotter/graphs/jkqtpgraphlabelstylemixin.h"
|
||||
|
||||
// forward declarations
|
||||
class JKQTBasePlotter;
|
||||
class JKQTPlotter;
|
||||
class JKQTPCoordinateAxis;
|
||||
class JKQTPDatastore;
|
||||
|
||||
|
||||
|
||||
/*! \brief This graph plots a series of data labels. This can be used to add number-labels to e.g. a barchart.
|
||||
\ingroup jkqtplotter_graphlabels
|
||||
|
||||
Sometimes it is necessary to display the numeric value of a datapoint right in the plot.
|
||||
To achieve this, JKQTPXYGraphLabels is provided, which draws a text-label next to each datapoint in a
|
||||
series of x- and y-values (thus it is derived from JKQTPXYGraph). Each label is drawn with a little offset
|
||||
from the actual datapoint. Under each label, a small (stylable) box is drawn, which is by default simply
|
||||
the same color as the background color of complete plot, but with transparency, thus providing a certain
|
||||
level of contrast to the text, even if drawn above other plot elements. Use the properties of the parent
|
||||
mix-in class JKQTPGraphValueLabelStyleMixin to style the text and the box.
|
||||
|
||||
Here is an example of labels together with a bars and lines chart:
|
||||
|
||||
\image html JKQTPGLabelAwayFromXAxis.png
|
||||
|
||||
To achieve this, use code like this:
|
||||
\code
|
||||
// create barchart and line-chart to display the data:
|
||||
JKQTPBarVerticalGraph* graph1=new JKQTPBarVerticalGraph(&plot);
|
||||
graph1->setBarPositionColumn(columnX);
|
||||
graph1->setBarHeightColumn(columnY);
|
||||
|
||||
JKQTPXYLineGraph* graph2=new JKQTPXYLineGraph(&plot);
|
||||
graph2->setXColumn(columnX);
|
||||
graph2->setYColumn(columnY);
|
||||
|
||||
// create the data labels:
|
||||
JKQTPXYGraphLabels* graphLabels=new JKQTPXYGraphLabels(JKQTPXYGraphLabels::YValueLabel, &plot);
|
||||
graphLabels->setXColumn(graph1->getXColumn());
|
||||
graphLabels->setYColumn(graph1->getYColumn());
|
||||
graphLabels->setLabelPosition(JKQTPGLabelAwayFromXAxis),
|
||||
|
||||
// add the graphs to the plot, so it is actually displayed
|
||||
plot.addGraph(graph1);
|
||||
plot.addGraph(graph2);
|
||||
plot.addGraph(graphLabels);
|
||||
\endcode
|
||||
|
||||
The text shown in the label is determined by a functor of type JKQTPXYGraphLabels::LabelGenerator that calculates
|
||||
it from the labels position and data-index.
|
||||
This functor can be custimized (set setCustomLabelGenerator() or the matching constructor), or it may be one of
|
||||
three default immplementations, that display:
|
||||
- the current x-value (JKQTPXYGraphLabels::XValueLabel constructor arguent or setDefaultXLabelGenerator() )
|
||||
- the current y-value (JKQTPXYGraphLabels::YValueLabel constructor arguent or setDefaultYLabelGenerator() )
|
||||
- the current x- and y-value (JKQTPXYGraphLabels::XYValueLabel constructor arguent or setDefaultXYLabelGenerator() )
|
||||
.
|
||||
|
||||
The default generators can be further customized with a series of properties on how to format their output:
|
||||
- setXValueLabelFormat(), setYValueLabelFormat(), setXYValueLabelFormat() ... these set the basic label and are
|
||||
typically only \c "$%1$" or \c "$%1/%2$" , but you can set them to any string (\c %1 / \c %2 is replaced by
|
||||
the string-converted x-/y-values) and e.g. add a prefix, like \c setXValueLabelFormat("$x=%1$").
|
||||
You can use any LaTeX-markup that is allowed by JKQTMathText here!
|
||||
- setXDefaultConverter(), setXDefaultPrecision(), setXBelowIsZero(), ... (all these exist in X and Y variants!)
|
||||
.
|
||||
|
||||
\see \ref JKQTPlotterGraphLabels
|
||||
|
||||
*/
|
||||
class JKQTPLOTTER_LIB_EXPORT JKQTPXYGraphLabels: public JKQTPXYGraph, public JKQTPGraphValueLabelStyleMixin, public JKQTPXYLabelsGeneratorMixin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum LabelContentsDefaultType {
|
||||
XValueLabel, //!< \brief generates a label with the x-coordinate only, calls setDefaultXLabelGenerator()
|
||||
YValueLabel, //!< \brief generates a label with the y-coordinate only, calls setDefaultYLabelGenerator()
|
||||
XYValueLabel //!< \brief generates a label with the x- and y-coordinate, calls setDefaultXYLabelGenerator()
|
||||
};
|
||||
Q_ENUM(LabelContentsDefaultType)
|
||||
/** \brief type of a functor that generates a label */
|
||||
typedef std::function<QString(double,double,int)> LabelGenerator;
|
||||
|
||||
/** \brief class constructor, generates a JKQTPXYGraphLabels with one of the default label generator functors (x-value, y-value or x+y-values) */
|
||||
explicit JKQTPXYGraphLabels(LabelContentsDefaultType lt, JKQTBasePlotter* parent=nullptr);
|
||||
/** \brief class constructor, generates a JKQTPXYGraphLabels with one of the default label generator functors (x-value, y-value or x+y-values) */
|
||||
JKQTPXYGraphLabels(LabelContentsDefaultType lt, JKQTPlotter* parent);
|
||||
/** \brief class constructor, generates a JKQTPXYGraphLabels with a custom LabelGenerator functor */
|
||||
JKQTPXYGraphLabels(const LabelGenerator& lgen, JKQTBasePlotter* parent=nullptr);
|
||||
/** \brief class constructor, generates a JKQTPXYGraphLabels with a custom LabelGenerator functor */
|
||||
JKQTPXYGraphLabels(const LabelGenerator& lgen, JKQTPlotter* parent);
|
||||
|
||||
/** \brief plots the graph to the plotter object specified as parent */
|
||||
virtual void draw(JKQTPEnhancedPainter& painter) override;
|
||||
/** \brief plots a key marker inside the specified rectangle \a rect */
|
||||
virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, const QRectF& rect) override;
|
||||
/** \brief returns the color to be used for the key label */
|
||||
virtual QColor getKeyLabelColor() const override;
|
||||
/** \copydoc JKQTPPlotElement::getXMinMax() */
|
||||
virtual bool getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) override;
|
||||
/** \copydoc JKQTPPlotElement::getYMinMax() */
|
||||
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
||||
|
||||
|
||||
/** \brief set color of line and symbol */
|
||||
void setColor(QColor c, bool setTextColor_=true, bool setFrameColor_=true);
|
||||
/** \brief sets a custom label geneator function of type LabelGenerator to use
|
||||
*
|
||||
* \see m_labelGenerator, setDefaultXLabelGenerator(), setDefaultYLabelGenerator(), setDefaultXYLabelGenerator()
|
||||
*/
|
||||
void setCustomLabelGenerator(const LabelGenerator& labgen);
|
||||
/** \brief sets the label geneator function to a default implementation, that prints the x-value only
|
||||
*
|
||||
* The generator uses m_xValueLabelFormat, m_xDefaultConverter, ...
|
||||
* \see m_labelGenerator, setCustomLabelGenerator(), setDefaultXLabelGenerator(), setDefaultYLabelGenerator(), setDefaultXYLabelGenerator()
|
||||
*/
|
||||
void setDefaultXLabelGenerator();
|
||||
/** \brief sets the label geneator function to a default implementation, that prints the y-value only
|
||||
*
|
||||
* The generator uses m_yValueLabelFormat, m_yDefaultConverter, ...
|
||||
* \see m_labelGenerator, setCustomLabelGenerator(), setDefaultXLabelGenerator(), setDefaultYLabelGenerator(), setDefaultXYLabelGenerator()
|
||||
*/
|
||||
void setDefaultYLabelGenerator();
|
||||
/** \brief sets the label geneator function to a default implementation, that prints the x- and y-value
|
||||
*
|
||||
* The generator uses m_xyValueLabelFormat, m_xDefaultConverter, m_yDefaultConverter, ...
|
||||
* \see m_labelGenerator, setCustomLabelGenerator(), setDefaultXLabelGenerator(), setDefaultYLabelGenerator(), setDefaultXYLabelGenerator()
|
||||
*/
|
||||
void setDefaultXYLabelGenerator();
|
||||
protected:
|
||||
/** \brief generates the label at position (\a x , \a y ) and at the given data \a index */
|
||||
QString generateLabel(double x, double y, int index) const;
|
||||
private:
|
||||
/** \brief generate the label for the datapoint at location (\a x , \a y ) and being the \a index -th value in the columns */
|
||||
LabelGenerator m_labelGenerator;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // jkqtpgraphlabels_H
|
524
lib/jkqtplotter/graphs/jkqtpgraphlabelstylemixin.cpp
Normal file
@ -0,0 +1,524 @@
|
||||
/*
|
||||
Copyright (c) 2008-2024 Jan W. Krieger (<jan@jkrieger.de>)
|
||||
|
||||
|
||||
|
||||
This software is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||
the Free Software Foundation, either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License (LGPL) for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "jkqtplotter/graphs/jkqtpgraphlabelstylemixin.h"
|
||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
|
||||
|
||||
QString JKQTPGraphLabelPosition2String(JKQTPGraphLabelPosition pos)
|
||||
{
|
||||
switch(pos) {
|
||||
case JKQTPGLabelAboveData: return "label_above_data";
|
||||
case JKQTPGLabelBelowData: return "label_below_data";
|
||||
case JKQTPGLabelLeftHandSide: return "label_left_hand_side";
|
||||
case JKQTPGLabelRightHandSide: return "label_right_hand_side";
|
||||
case JKQTPGLabelAwayFromXAxis: return "label_away_from_xaxis";
|
||||
case JKQTPGLabelAwayFromYAxis: return "label_away_from_yaxis";
|
||||
case JKQTPGLabelTowardsXAxis: return "label_towards_xaxis";
|
||||
case JKQTPGLabelTowardsYAxis: return "label_towards_xaxis";
|
||||
}
|
||||
return "label_away_from_xaxis";
|
||||
}
|
||||
|
||||
JKQTPGraphLabelPosition String2JKQTPGraphLabelPosition(const QString &pos)
|
||||
{
|
||||
const QString m=pos.trimmed().toLower();
|
||||
if (m=="label_above_data" || m=="above_data" || m=="above") return JKQTPGLabelAboveData;
|
||||
if (m=="label_below_data" || m=="below_data" || m=="below") return JKQTPGLabelBelowData;
|
||||
if (m=="label_left_hand_side" || m=="left_hand_side" || m=="left_hand" || m=="left" || m=="lhs") return JKQTPGLabelLeftHandSide;
|
||||
if (m=="label_right_hand_side" || m=="right_hand_side" || m=="right_hand" || m=="right" || m=="rhs") return JKQTPGLabelRightHandSide;
|
||||
if (m=="label_away_from_xaxis" || m=="away_from_xaxis") return JKQTPGLabelAwayFromXAxis;
|
||||
if (m=="label_away_from_yaxis" || m=="away_from_yaxis") return JKQTPGLabelAwayFromYAxis;
|
||||
if (m=="label_towars_xaxis" || m=="towars_xaxis") return JKQTPGLabelTowardsXAxis;
|
||||
if (m=="label_towars_yaxis" || m=="towars_yaxis") return JKQTPGLabelTowardsYAxis;
|
||||
return JKQTPGraphLabelDefault;
|
||||
}
|
||||
|
||||
QString JKQTPGraphLabelBoxType2String(JKQTPGraphLabelBoxType pos)
|
||||
{
|
||||
switch(pos) {
|
||||
case JKQTPGLSimpleBox: return "simple_box";
|
||||
case JKQTPGLSimpleBoxAndLine: return "simple_box_and_line";
|
||||
}
|
||||
return "simple_box";
|
||||
}
|
||||
|
||||
JKQTPGraphLabelBoxType String2JKQTPGraphLabelBoxType(const QString &pos)
|
||||
{
|
||||
const QString m=pos.trimmed().toLower();
|
||||
if (m=="simple_box" || m=="simple" || m=="box") return JKQTPGLSimpleBox;
|
||||
if (m=="simple_box_and_line" || m=="box_and_line") return JKQTPGLSimpleBoxAndLine;
|
||||
return JKQTPGraphLabelBoxDefault;
|
||||
}
|
||||
|
||||
|
||||
|
||||
JKQTPGraphValueLabelStyleMixin::JKQTPGraphValueLabelStyleMixin(JKQTBasePlotter *parent):
|
||||
JKQTPGraphTextStyleMixin(parent), JKQTPGraphLineStyleMixin(), JKQTPGraphFillStyleMixin()
|
||||
{
|
||||
m_labelOffset=getTextFontSize()/4.0;
|
||||
m_labelOffsetWithConnector=getTextFontSize()*0.75;
|
||||
m_labelBoxRounding=getTextFontSize()/3.0;
|
||||
m_labelXPadding=getTextFontSize()/3.0;
|
||||
m_labelYPadding=getTextFontSize()/8.0;
|
||||
m_labelPosition=JKQTPGraphLabelDefault;
|
||||
m_labelBoxType=JKQTPGLSimpleBox;
|
||||
m_drawLabelBoxFrame=false;
|
||||
setFillStyle(Qt::NoBrush);
|
||||
}
|
||||
|
||||
void JKQTPGraphValueLabelStyleMixin::initValueLabelStyle(JKQTBasePlotter *parent, int &parentPlotStyle, JKQTPPlotStyleType styletype)
|
||||
{
|
||||
|
||||
setFillStyle(Qt::NoBrush);
|
||||
if (parent) { // get style settings from parent object
|
||||
initTextStyle(parent, parentPlotStyle,styletype);
|
||||
initLineStyle(parent, parentPlotStyle, styletype);
|
||||
initFillStyle(parent, parentPlotStyle, styletype);
|
||||
setFillColor(QColorWithAlphaF(parent->getCurrentPlotterStyle().plotBackgroundBrush.color(), 0.5));
|
||||
setFillStyle(Qt::SolidPattern);
|
||||
setLineWidth(parent->getCurrentPlotterStyle().keyStyle.frameWidth);
|
||||
}
|
||||
}
|
||||
|
||||
JKQTPGraphValueLabelStyleMixin::~JKQTPGraphValueLabelStyleMixin()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void JKQTPGraphValueLabelStyleMixin::setLabelOffset(double r)
|
||||
{
|
||||
m_labelOffset=r;
|
||||
}
|
||||
|
||||
double JKQTPGraphValueLabelStyleMixin::getLabelOffset() const
|
||||
{
|
||||
return m_labelOffset;
|
||||
}
|
||||
|
||||
double JKQTPGraphValueLabelStyleMixin::getUsedLabelOffset() const
|
||||
{
|
||||
if (m_labelBoxType==JKQTPGLSimpleBox) {
|
||||
return m_labelOffset;
|
||||
}
|
||||
|
||||
return m_labelOffsetWithConnector;
|
||||
}
|
||||
|
||||
void JKQTPGraphValueLabelStyleMixin::setLabelOffsetWithConnector(double r)
|
||||
{
|
||||
m_labelOffsetWithConnector=r;
|
||||
}
|
||||
|
||||
double JKQTPGraphValueLabelStyleMixin::getLabelOffsetWithConnector() const
|
||||
{
|
||||
return m_labelOffsetWithConnector;
|
||||
}
|
||||
void JKQTPGraphValueLabelStyleMixin::setLabelBoxRounding(double r)
|
||||
{
|
||||
m_labelBoxRounding=r;
|
||||
}
|
||||
|
||||
double JKQTPGraphValueLabelStyleMixin::getLabelBoxRounding() const
|
||||
{
|
||||
return m_labelBoxRounding;
|
||||
}
|
||||
|
||||
void JKQTPGraphValueLabelStyleMixin::setLabelXPadding(double r)
|
||||
{
|
||||
m_labelXPadding=r;
|
||||
}
|
||||
|
||||
double JKQTPGraphValueLabelStyleMixin::getLabelXPadding() const
|
||||
{
|
||||
return m_labelXPadding;
|
||||
}
|
||||
|
||||
void JKQTPGraphValueLabelStyleMixin::setLabelYPadding(double r)
|
||||
{
|
||||
m_labelYPadding=r;
|
||||
}
|
||||
|
||||
double JKQTPGraphValueLabelStyleMixin::getLabelYPadding() const
|
||||
{
|
||||
return m_labelYPadding;
|
||||
}
|
||||
|
||||
void JKQTPGraphValueLabelStyleMixin::setLabelPosition(JKQTPGraphLabelPosition r)
|
||||
{
|
||||
m_labelPosition=r;
|
||||
}
|
||||
|
||||
JKQTPGraphLabelPosition JKQTPGraphValueLabelStyleMixin::getLabelPosition() const
|
||||
{
|
||||
return m_labelPosition;
|
||||
}
|
||||
|
||||
bool JKQTPGraphValueLabelStyleMixin::isLabelPositioningGrowingInX() const
|
||||
{
|
||||
switch (m_labelPosition) {
|
||||
case JKQTPGLabelAwayFromYAxis:
|
||||
case JKQTPGLabelLeftHandSide:
|
||||
case JKQTPGLabelRightHandSide:
|
||||
return true;
|
||||
case JKQTPGLabelAboveData:
|
||||
case JKQTPGLabelBelowData:
|
||||
case JKQTPGLabelAwayFromXAxis:
|
||||
case JKQTPGLabelTowardsXAxis:
|
||||
case JKQTPGLabelTowardsYAxis:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JKQTPGraphValueLabelStyleMixin::isLabelPositioningGrowingInY() const
|
||||
{
|
||||
switch (m_labelPosition) {
|
||||
case JKQTPGLabelAwayFromXAxis:
|
||||
case JKQTPGLabelAboveData:
|
||||
case JKQTPGLabelBelowData:
|
||||
return true;
|
||||
case JKQTPGLabelAwayFromYAxis:
|
||||
case JKQTPGLabelTowardsXAxis:
|
||||
case JKQTPGLabelTowardsYAxis:
|
||||
case JKQTPGLabelLeftHandSide:
|
||||
case JKQTPGLabelRightHandSide:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void JKQTPGraphValueLabelStyleMixin::setDrawLabelBoxFrame(bool r)
|
||||
{
|
||||
m_drawLabelBoxFrame=r;
|
||||
}
|
||||
|
||||
bool JKQTPGraphValueLabelStyleMixin::drawsLabelBoxFrame() const
|
||||
{
|
||||
return m_drawLabelBoxFrame;
|
||||
}
|
||||
|
||||
void JKQTPGraphValueLabelStyleMixin::setLabelBoxType(JKQTPGraphLabelBoxType r)
|
||||
{
|
||||
m_labelBoxType=r;
|
||||
}
|
||||
|
||||
JKQTPGraphLabelBoxType JKQTPGraphValueLabelStyleMixin::getLabelBoxType() const
|
||||
{
|
||||
return m_labelBoxType;
|
||||
}
|
||||
|
||||
void JKQTPGraphValueLabelStyleMixin::drawLabel(JKQTPEnhancedPainter &painter, const QPointF &xDataPixel, const QPointF &xData, const QString &contents, JKQTBasePlotter *parent) const
|
||||
{
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
|
||||
// calculate geometry
|
||||
const LabelGeometry g=calcLabelGeometry(painter, xDataPixel, xData, contents, parent);
|
||||
|
||||
// draw Box
|
||||
if (m_drawLabelBoxFrame) painter.setPen(getLinePenForRects(painter, parent));
|
||||
else painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(getFillBrush(painter, parent));
|
||||
if (m_labelBoxType==JKQTPGLSimpleBox || m_labelBoxType==JKQTPGLSimpleBoxAndLine) {
|
||||
painter.drawRoundedRectOrRect(g.boxRect, m_labelBoxRounding);
|
||||
}
|
||||
if (m_labelBoxType==JKQTPGLSimpleBoxAndLine) {
|
||||
//qDebug()<<"linestyle="<<getLineStyle()<<", color="<<getLineColor()<<", width="<<getLineWidth();
|
||||
painter.setPen(getLinePen(painter, parent));
|
||||
switch(g.boxpos) {
|
||||
case LabelGeometry::BoxLeft:
|
||||
painter.drawLine(xDataPixel, QPointF(qMax(g.boxRect.left(),g.boxRect.right()), xDataPixel.y()));
|
||||
break;
|
||||
case LabelGeometry::BoxRight:
|
||||
painter.drawLine(xDataPixel, QPointF(qMin(g.boxRect.left(),g.boxRect.right()), xDataPixel.y()));
|
||||
break;
|
||||
case LabelGeometry::BoxTop:
|
||||
painter.drawLine(xDataPixel, QPointF(xDataPixel.x(), qMax(g.boxRect.top(),g.boxRect.bottom())));
|
||||
break;
|
||||
case LabelGeometry::BoxBottom:
|
||||
painter.drawLine(xDataPixel, QPointF(xDataPixel.x(), qMin(g.boxRect.top(),g.boxRect.bottom())));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// draw text
|
||||
parent->getMathText()->setFontSpecial(getTextFontName());
|
||||
parent->getMathText()->setFontSize(getTextFontSize()*parent->getFontSizeMultiplier());
|
||||
parent->getMathText()->setFontColor(getTextColor());
|
||||
parent->getMathText()->parse(contents);
|
||||
parent->getMathText()->draw(painter, Qt::AlignVCenter|Qt::AlignHCenter, g.textRect, parent->getCurrentPlotterStyle().debugShowTextBoxes);
|
||||
}
|
||||
|
||||
JKQTPGraphValueLabelStyleMixin::LabelGeometry JKQTPGraphValueLabelStyleMixin::calcLabelGeometry(JKQTPEnhancedPainter &painter, const QPointF &xDataPixel, const QPointF &xData, const QString &contents, JKQTBasePlotter *parent) const
|
||||
{
|
||||
LabelGeometry res;
|
||||
res.label=contents;
|
||||
res.labelOffsetPx=parent->pt2px(getUsedLabelOffset(),painter);
|
||||
res.padX=parent->pt2px(m_labelXPadding,painter);
|
||||
res.padY=parent->pt2px(m_labelYPadding,painter);
|
||||
res.lw=parent->pt2px(getLineWidth(),painter);
|
||||
res.textSize=parent->getTextSizeDetail(getTextFontName(), getTextFontSize(), contents, painter);
|
||||
|
||||
if(m_labelPosition==JKQTPGLabelAboveData || (m_labelPosition==JKQTPGLabelAwayFromXAxis && xData.y()>=0) || (m_labelPosition==JKQTPGLabelTowardsXAxis && xData.y()<0)) {
|
||||
// label above
|
||||
res.textRect=QRectF(xDataPixel.x()-res.textSize.width/2.0, xDataPixel.y()-res.labelOffsetPx-res.padY-res.lw/2.0-res.textSize.overallHeight, res.textSize.width, res.textSize.overallHeight);
|
||||
res.boxpos=LabelGeometry::BoxTop;
|
||||
} else if (m_labelPosition==JKQTPGLabelBelowData || (m_labelPosition==JKQTPGLabelAwayFromXAxis && xData.y()<0) || (m_labelPosition==JKQTPGLabelTowardsXAxis && xData.y()>=0)) {
|
||||
// label below
|
||||
res.textRect=QRectF(xDataPixel.x()-res.textSize.width/2.0, xDataPixel.y()+res.labelOffsetPx+res.padY+res.lw/2.0, res.textSize.width, res.textSize.overallHeight);
|
||||
res.boxpos=LabelGeometry::BoxBottom;
|
||||
} else if(m_labelPosition==JKQTPGLabelLeftHandSide || (m_labelPosition==JKQTPGLabelAwayFromYAxis && xData.x()<0) || (m_labelPosition==JKQTPGLabelTowardsYAxis && xData.x()>=0)) {
|
||||
// lhs
|
||||
res.textRect=QRectF(xDataPixel.x()-res.labelOffsetPx-res.padX-res.lw/2.0-res.textSize.width, xDataPixel.y()-res.textSize.overallHeight/2.0, res.textSize.width, res.textSize.overallHeight);
|
||||
res.boxpos=LabelGeometry::BoxLeft;
|
||||
} else if (m_labelPosition==JKQTPGLabelRightHandSide || (m_labelPosition==JKQTPGLabelAwayFromYAxis && xData.x()>=0) || (m_labelPosition==JKQTPGLabelTowardsYAxis && xData.x()<0)) {
|
||||
// rhs
|
||||
res.textRect=QRectF(xDataPixel.x()+res.labelOffsetPx+res.padX+res.lw/2.0, xDataPixel.y()-res.textSize.overallHeight/2.0, res.textSize.width, res.textSize.overallHeight);
|
||||
res.boxpos=LabelGeometry::BoxRight;
|
||||
}
|
||||
|
||||
res.boxRect=QRectF(res.textRect.x()-res.padX-res.lw/2.0, res.textRect.y()-res.padY-res.lw/2.0, res.textRect.width()+res.padX*2.0+res.lw, res.textRect.height()+res.padY*2.0+res.lw);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
JKQTPXYLabelsGeneratorMixin::JKQTPXYLabelsGeneratorMixin():
|
||||
m_xValueLabelFormat("$%1$"),
|
||||
m_yValueLabelFormat("$%1$"),
|
||||
m_xyValueLabelFormat("$%1 / %2$"),
|
||||
m_xDefaultConverter(JKQTPGLDefaultConverter),
|
||||
m_yDefaultConverter(JKQTPGLDefaultConverter),
|
||||
m_xDefaultPrecision(4),
|
||||
m_yDefaultPrecision(4),
|
||||
m_xBelowIsZero(std::numeric_limits<double>::min()*4),
|
||||
m_yBelowIsZero(std::numeric_limits<double>::min()*4),
|
||||
m_xMinNoExponent(1e-3),
|
||||
m_yMinNoExponent(1e-3),
|
||||
m_xMaxNoExponent(1e4),
|
||||
m_yMaxNoExponent(1e4),
|
||||
m_xDateTimeFormat(QLocale().dateTimeFormat(QLocale::NarrowFormat)),
|
||||
m_yDateTimeFormat(QLocale().dateTimeFormat(QLocale::NarrowFormat))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JKQTPXYLabelsGeneratorMixin::~JKQTPXYLabelsGeneratorMixin()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int JKQTPXYLabelsGeneratorMixin::getXDefaultPrecision() const
|
||||
{
|
||||
return m_xDefaultPrecision;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setXDefaultPrecision(int v)
|
||||
{
|
||||
m_xDefaultPrecision=v;
|
||||
}
|
||||
|
||||
int JKQTPXYLabelsGeneratorMixin::getYDefaultPrecision() const
|
||||
{
|
||||
return m_yDefaultPrecision;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setYDefaultPrecision(int v)
|
||||
{
|
||||
m_yDefaultPrecision=v;
|
||||
}
|
||||
|
||||
JKQTPGraphLabelConverterType JKQTPXYLabelsGeneratorMixin::getXDefaultConverter() const
|
||||
{
|
||||
return m_xDefaultConverter;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setXDefaultConverter(JKQTPGraphLabelConverterType v)
|
||||
{
|
||||
m_xDefaultConverter=v;
|
||||
}
|
||||
|
||||
JKQTPGraphLabelConverterType JKQTPXYLabelsGeneratorMixin::getYDefaultConverter() const
|
||||
{
|
||||
return m_yDefaultConverter;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setYDefaultConverter(JKQTPGraphLabelConverterType v)
|
||||
{
|
||||
m_yDefaultConverter=v;
|
||||
}
|
||||
|
||||
QString JKQTPXYLabelsGeneratorMixin::getXValueLabelFormat() const
|
||||
{
|
||||
return m_xValueLabelFormat;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setXValueLabelFormat(const QString &v)
|
||||
{
|
||||
m_xValueLabelFormat=v;
|
||||
}
|
||||
|
||||
QString JKQTPXYLabelsGeneratorMixin::getYValueLabelFormat() const
|
||||
{
|
||||
return m_yValueLabelFormat;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setYValueLabelFormat(const QString &v)
|
||||
{
|
||||
m_yValueLabelFormat=v;
|
||||
}
|
||||
|
||||
QString JKQTPXYLabelsGeneratorMixin::getXYValueLabelFormat() const
|
||||
{
|
||||
return m_xyValueLabelFormat;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setXYValueLabelFormat(const QString &v)
|
||||
{
|
||||
m_xyValueLabelFormat=v;
|
||||
}
|
||||
|
||||
double JKQTPXYLabelsGeneratorMixin::getXBelowIsZero() const
|
||||
{
|
||||
return m_xBelowIsZero;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setXBelowIsZero(double v)
|
||||
{
|
||||
m_xBelowIsZero=v;
|
||||
}
|
||||
|
||||
double JKQTPXYLabelsGeneratorMixin::getYBelowIsZero() const
|
||||
{
|
||||
return m_yBelowIsZero;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setYBelowIsZero(double v)
|
||||
{
|
||||
m_yBelowIsZero=v;
|
||||
}
|
||||
|
||||
double JKQTPXYLabelsGeneratorMixin::getXMinNoExponent() const
|
||||
{
|
||||
return m_xMinNoExponent;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setXMinNoExponent(double v)
|
||||
{
|
||||
m_xMinNoExponent=v;
|
||||
}
|
||||
|
||||
double JKQTPXYLabelsGeneratorMixin::getYMinNoExponent() const
|
||||
{
|
||||
return m_yMinNoExponent;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setYMinNoExponent(double v)
|
||||
{
|
||||
m_yMinNoExponent=v;
|
||||
}
|
||||
|
||||
double JKQTPXYLabelsGeneratorMixin::getXMaxNoExponent() const
|
||||
{
|
||||
return m_xMaxNoExponent;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setXMaxNoExponent(double v)
|
||||
{
|
||||
m_xMaxNoExponent=v;
|
||||
}
|
||||
|
||||
double JKQTPXYLabelsGeneratorMixin::getYMaxNoExponent() const
|
||||
{
|
||||
return m_yMaxNoExponent;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setYMaxNoExponent(double v)
|
||||
{
|
||||
m_yMaxNoExponent=v;
|
||||
}
|
||||
|
||||
QString JKQTPXYLabelsGeneratorMixin::getXDateTimeFormmat() const
|
||||
{
|
||||
return m_xDateTimeFormat;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setXDateTimeFormmat(const QString &v)
|
||||
{
|
||||
m_xDateTimeFormat=v;
|
||||
}
|
||||
|
||||
QString JKQTPXYLabelsGeneratorMixin::getYDateTimeFormmat() const
|
||||
{
|
||||
return m_yDateTimeFormat;
|
||||
}
|
||||
|
||||
void JKQTPXYLabelsGeneratorMixin::setYDateTimeFormmat(const QString &v)
|
||||
{
|
||||
m_yDateTimeFormat=v;
|
||||
}
|
||||
|
||||
|
||||
QString JKQTPXYLabelsGeneratorMixin::generateDefaultXLabel(double x, double , int ) const
|
||||
{
|
||||
return m_xValueLabelFormat.arg(xValToString(x));
|
||||
}
|
||||
|
||||
QString JKQTPXYLabelsGeneratorMixin::generateDefaultYLabel(double , double y, int ) const
|
||||
{
|
||||
return m_yValueLabelFormat.arg(yValToString(y));
|
||||
}
|
||||
|
||||
QString JKQTPXYLabelsGeneratorMixin::generateDefaultXYLabel(double x, double y, int ) const
|
||||
{
|
||||
return m_xyValueLabelFormat.arg(xValToString(x)).arg(yValToString(y));
|
||||
}
|
||||
|
||||
QString JKQTPXYLabelsGeneratorMixin::valToString(double x, JKQTPGraphLabelConverterType converter, int precision, double belowIsZero, double minNoExponent, double maxNoExponent, const QString& dateTimeFormat)
|
||||
{
|
||||
switch(converter) {
|
||||
case JKQTPGLCdecimal: return jkqtp_floattoqstr(x,'f',precision,true);
|
||||
case JKQTPGLCscientific: return jkqtp_floattoqstr(x,'e',precision,true);
|
||||
case JKQTPGLCexponentCharacter: return jkqtp_floattolatexunitqstr(x,precision,true, belowIsZero);
|
||||
case JKQTPGLCexponent: return jkqtp_floattolatexqstr(x,precision,true, belowIsZero,minNoExponent,maxNoExponent);
|
||||
case JKQTPGLCdatetime: {
|
||||
QDateTime dt;
|
||||
dt.setMSecsSinceEpoch(uint64_t(x));
|
||||
return dt.toString(dateTimeFormat);
|
||||
}
|
||||
}
|
||||
qWarning()<<"unknown m_xDefaultConverter="<<converter<<" in JKQTPXYLabelsGeneratorMixin::xValToString()";
|
||||
return "";
|
||||
}
|
||||
|
||||
QString JKQTPXYLabelsGeneratorMixin::xValToString(double x) const
|
||||
{
|
||||
return valToString(x, m_xDefaultConverter,m_xDefaultPrecision, m_xBelowIsZero, m_xMinNoExponent,m_xMaxNoExponent, m_xDateTimeFormat);
|
||||
}
|
||||
|
||||
QString JKQTPXYLabelsGeneratorMixin::yValToString(double x) const
|
||||
{
|
||||
return valToString(x, m_yDefaultConverter,m_yDefaultPrecision, m_yBelowIsZero, m_yMinNoExponent,m_yMaxNoExponent, m_yDateTimeFormat);
|
||||
}
|
||||
|
||||
|
429
lib/jkqtplotter/graphs/jkqtpgraphlabelstylemixin.h
Normal file
@ -0,0 +1,429 @@
|
||||
/*
|
||||
Copyright (c) 2008-2024 Jan W. Krieger (<jan@jkrieger.de>)
|
||||
|
||||
|
||||
|
||||
This software is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||
the Free Software Foundation, either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License (LGPL) for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef jkqtpgraphlabelstylemixin_H
|
||||
#define jkqtpgraphlabelstylemixin_H
|
||||
|
||||
|
||||
#include <QString>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <QBrush>
|
||||
#include "jkqtplotter/jkqtptools.h"
|
||||
#include "jkqtplotter/jkqtplotter_imexport.h"
|
||||
#include "jkqtplotter/jkqtpbaseplotter.h"
|
||||
#include "jkqtcommon/jkqtpdrawingtools.h"
|
||||
#include "jkqtplotter/jkqtplotter_configmacros.h"
|
||||
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
||||
|
||||
|
||||
class JKQTPlotter; // forward
|
||||
|
||||
|
||||
|
||||
/** \brief position of a label near a data-point, used by JKQTPGraphValueLabelStyleMixin
|
||||
* \ingroup jkqtplotter_specialgraphs_stylemixins
|
||||
*
|
||||
* \see JKQTPGraphValueLabelStyleMixin
|
||||
*/
|
||||
enum JKQTPGraphLabelPosition {
|
||||
JKQTPGLabelAboveData=0, /*!< \brief all labels always above the datapoint \image html JKQTPGLabelAboveData.png */
|
||||
JKQTPGLabelBelowData, /*!< \brief all labels always below the datapoint \image html JKQTPGLabelBelowData.png */
|
||||
JKQTPGLabelTowardsXAxis, /*!< \brief all labels between the datapoint and the x-axis the datapoint \image html JKQTPGLabelTowardsXAxis.png */
|
||||
JKQTPGLabelAwayFromXAxis, /*!< \brief all labels pointing away from the x-axis \image html JKQTPGLabelAwayFromXAxis.png */
|
||||
JKQTPGLabelRightHandSide, /*!< \brief all labels always on the right-hand side of the datapoint \image html JKQTPGLabelRightHandSide.png */
|
||||
JKQTPGLabelLeftHandSide, /*!< \brief all labels always on the left-hand side of the datapoint \image html JKQTPGLabelLeftHandSide.png */
|
||||
JKQTPGLabelTowardsYAxis, /*!< \brief all labels between the datapoint and the y-axis the datapoint \image html JKQTPGLabelTowardsYAxis.png */
|
||||
JKQTPGLabelAwayFromYAxis, /*!< \brief all labels pointing away from the y-axis \image html JKQTPGLabelAwayFromYAxis.png */
|
||||
|
||||
JKQTPGraphLabelDefault=JKQTPGLabelAwayFromXAxis,
|
||||
};
|
||||
|
||||
|
||||
/** \brief converts a JKQTPGraphLabelPosition variable into a human-readable string
|
||||
* \ingroup jkqtplotter_specialgraphs_stylemixins
|
||||
*/
|
||||
JKQTPLOTTER_LIB_EXPORT QString JKQTPGraphLabelPosition2String(JKQTPGraphLabelPosition pos);
|
||||
|
||||
/** \brief converts a String into a JKQTPGraphLabelPosition
|
||||
* \ingroup jkqtplotter_specialgraphs_stylemixins
|
||||
*/
|
||||
JKQTPLOTTER_LIB_EXPORT JKQTPGraphLabelPosition String2JKQTPGraphLabelPosition(const QString& pos);
|
||||
|
||||
/** \brief type of box surrounding a label near a data-point, used by JKQTPGraphValueLabelStyleMixin
|
||||
* \ingroup jkqtplotter_specialgraphs_stylemixins
|
||||
*
|
||||
* \see JKQTPGraphValueLabelStyleMixin
|
||||
*/
|
||||
enum JKQTPGraphLabelBoxType {
|
||||
JKQTPGLSimpleBox=0, /*!< \brief a simple (possibly rounded and outlined) box \image html JKQTPGLSimpleBox.png */
|
||||
JKQTPGLSimpleBoxAndLine=1, /*!< \brief a simple (possibly rounded and outlined) box, connected to the datapoint by a line \image html JKQTPGLSimpleBoxAndLine.png */
|
||||
|
||||
JKQTPGraphLabelBoxDefault=JKQTPGLSimpleBox,
|
||||
};
|
||||
|
||||
|
||||
/** \brief converts a JKQTPGraphLabelBoxType variable into a human-readable string
|
||||
* \ingroup jkqtplotter_specialgraphs_stylemixins
|
||||
*/
|
||||
JKQTPLOTTER_LIB_EXPORT QString JKQTPGraphLabelBoxType2String(JKQTPGraphLabelBoxType pos);
|
||||
|
||||
/** \brief converts a String into a JKQTPGraphLabelBoxType
|
||||
* \ingroup jkqtplotter_specialgraphs_stylemixins
|
||||
*/
|
||||
JKQTPLOTTER_LIB_EXPORT JKQTPGraphLabelBoxType String2JKQTPGraphLabelBoxType(const QString& pos);
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief This Mix-In class provides setter/getter methods, storage and other facilities for value labels in graphs
|
||||
\ingroup jkqtplotter_specialgraphs_stylemixins
|
||||
|
||||
in addition to all properties of JKQTPGraphTextStyleMixin for the actual label text,
|
||||
JKQTPGraphLineStyleMixin & JKQTPGraphFillStyleMixin for a box around the label,
|
||||
it also supports properties for positioning and further sryling the labels.
|
||||
|
||||
supported properties:
|
||||
- padding from actual label to border
|
||||
- distance of label to actual datapoint
|
||||
- positioning of the label
|
||||
- styling for the box around the label
|
||||
.
|
||||
|
||||
\image html jkqtpxygraphlabels.png
|
||||
|
||||
\see JKQTPGraphTextStyleMixin, JKQTPGraphLineStyleMixin, JKQTPGraphFillStyleMixin, JKQTPXYGraphLabels
|
||||
*/
|
||||
class JKQTPLOTTER_LIB_EXPORT JKQTPGraphValueLabelStyleMixin: public JKQTPGraphTextStyleMixin, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
|
||||
#ifndef JKQTPLOTTER_WORKAROUND_QGADGET_BUG
|
||||
Q_GADGET
|
||||
#endif
|
||||
public:
|
||||
|
||||
|
||||
/** \brief class constructor */
|
||||
JKQTPGraphValueLabelStyleMixin(JKQTBasePlotter *parent);
|
||||
|
||||
/** \brief initiaize the fill style (from the parent plotter) */
|
||||
void initValueLabelStyle(JKQTBasePlotter* parent, int &parentPlotStyle, JKQTPPlotStyleType styletype=JKQTPPlotStyleType::Default);
|
||||
|
||||
virtual ~JKQTPGraphValueLabelStyleMixin();
|
||||
|
||||
/** \copydoc m_labelOffset */
|
||||
void setLabelOffset(double r);
|
||||
/** \copydoc m_labelOffset */
|
||||
double getLabelOffset() const;
|
||||
/** \brief determines, whether to use getLabelOffset() or getLabelOffsetWithConnector() (or something else) and returns it */
|
||||
double getUsedLabelOffset() const;
|
||||
|
||||
/** \copydoc m_labelOffsetWithConnector */
|
||||
void setLabelOffsetWithConnector(double r);
|
||||
/** \copydoc m_labelOffsetWithConnector */
|
||||
double getLabelOffsetWithConnector() const;
|
||||
|
||||
/** \copydoc m_labelBoxRounding */
|
||||
void setLabelBoxRounding(double r);
|
||||
/** \copydoc m_labelBoxRounding */
|
||||
double getLabelBoxRounding() const;
|
||||
|
||||
/** \copydoc m_labelXPadding */
|
||||
void setLabelXPadding(double r);
|
||||
/** \copydoc m_labelXPadding */
|
||||
double getLabelXPadding() const;
|
||||
|
||||
|
||||
/** \copydoc m_labelYPadding */
|
||||
void setLabelYPadding(double r);
|
||||
/** \copydoc m_labelYPadding */
|
||||
double getLabelYPadding() const;
|
||||
|
||||
/** \copydoc m_labelPosition */
|
||||
void setLabelPosition(JKQTPGraphLabelPosition r);
|
||||
/** \copydoc m_labelPosition */
|
||||
JKQTPGraphLabelPosition getLabelPosition() const;
|
||||
/** \brief determines whether a label is positioned left of the mininmum, or right of the maxinmum datapoint (\c true ) */
|
||||
bool isLabelPositioningGrowingInX() const;
|
||||
/** \brief determines whether a label is positioned below the mininmum, or above the maxinmum datapoint (\c true ) */
|
||||
bool isLabelPositioningGrowingInY() const;
|
||||
|
||||
/** \copydoc m_drawLabelBoxFrame */
|
||||
void setDrawLabelBoxFrame(bool r);
|
||||
/** \copydoc m_drawLabelBoxFrame */
|
||||
bool drawsLabelBoxFrame() const;
|
||||
|
||||
/** \copydoc m_labelBoxType */
|
||||
void setLabelBoxType(JKQTPGraphLabelBoxType r);
|
||||
/** \copydoc m_labelBoxType */
|
||||
JKQTPGraphLabelBoxType getLabelBoxType() const;
|
||||
|
||||
/** \brief draws a label, including its box
|
||||
*
|
||||
* \brief painter the JKQTPEnhancedPainter to use for drawing
|
||||
* \brief xDataPixel position of the labeled datapoint in (screen) pixels
|
||||
* \brief xData x- and y-coordinate of the datapoint (needed for some JKQTPGraphLabelPosition)
|
||||
* \brief contents the text to be rendered
|
||||
* \brief parent the JKQTPBasePlotter in whos context we are drawing (e.g. needed to render \a contents )
|
||||
*
|
||||
*/
|
||||
void drawLabel(JKQTPEnhancedPainter& painter, const QPointF& xDataPixel, const QPointF& xData, const QString& contents, JKQTBasePlotter *parent) const;
|
||||
|
||||
|
||||
|
||||
#ifndef JKQTPLOTTER_WORKAROUND_QGADGET_BUG
|
||||
Q_PROPERTY(double labelOffset MEMBER m_labelOffset READ getLabelOffset WRITE setLabelOffset)
|
||||
Q_PROPERTY(double labelOffsetWithConnector MEMBER m_labelOffsetWithConnector READ getLabelOffsetWithConnector WRITE setLabelOffsetWithConnector)
|
||||
Q_PROPERTY(double labelBoxRounding MEMBER m_labelBoxRounding READ getLabelBoxRounding WRITE setLabelBoxRounding)
|
||||
Q_PROPERTY(double labelXPadding MEMBER m_labelXPadding READ getLabelXPadding WRITE setLabelXPadding)
|
||||
Q_PROPERTY(double labelYPadding MEMBER m_labelYPadding READ getLabelYPadding WRITE setLabelYPadding)
|
||||
Q_PROPERTY(JKQTPGraphLabelPosition labelPosition MEMBER m_labelPosition READ getLabelPosition WRITE setLabelPosition)
|
||||
Q_PROPERTY(bool drawLabelBoxFrame MEMBER m_drawLabelBoxFrame READ drawsLabelBoxFrame WRITE setDrawLabelBoxFrame)
|
||||
Q_PROPERTY(JKQTPGraphLabelBoxType labelBoxType MEMBER m_labelBoxType READ getLabelBoxType WRITE setLabelBoxType)
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/** \brief describes details about the geometry of a label, used by calcLabelGeometry() */
|
||||
struct LabelGeometry {
|
||||
inline LabelGeometry():
|
||||
labelOffsetPx(0.0),
|
||||
padX(0.0),
|
||||
padY(0.0),
|
||||
lw(0.0),
|
||||
label(""),
|
||||
textSize(),
|
||||
textRect(),
|
||||
boxRect(),
|
||||
boxpos(BoxTop)
|
||||
{ };
|
||||
double labelOffsetPx;
|
||||
double padX;
|
||||
double padY;
|
||||
double lw;
|
||||
QString label;
|
||||
JKQTMathTextNodeSize textSize;
|
||||
QRectF textRect;
|
||||
QRectF boxRect;
|
||||
enum BoxPos {
|
||||
BoxLeft,
|
||||
BoxRight,
|
||||
BoxTop,
|
||||
BoxBottom
|
||||
};
|
||||
BoxPos boxpos;
|
||||
};
|
||||
|
||||
/** \brief calculate everything that is necessary to draw a label, including its box
|
||||
*
|
||||
* \brief painter the JKQTPEnhancedPainter to use for drawing
|
||||
* \brief xDataPixel position of the labeled datapoint in (screen) pixels
|
||||
* \brief xData x- and y-coordinate of the datapoint (needed for some JKQTPGraphLabelPosition)
|
||||
* \brief contents the text to be rendered
|
||||
* \brief parent the JKQTPBasePlotter in whos context we are drawing (e.g. needed to render \a contents )
|
||||
*
|
||||
*/
|
||||
LabelGeometry calcLabelGeometry(JKQTPEnhancedPainter& painter, const QPointF& xDataPixel, const QPointF& xData, const QString& contents, JKQTBasePlotter *parent) const;
|
||||
|
||||
private:
|
||||
/** \brief offset of the box rectangle to the actual data point location [pt], this is used for simple boxes and is a rather close distance (e.g. JKQTPGLSimpleBox)
|
||||
*
|
||||
* \see setLabelOffset(), getLabelOffset(), setLabelOffsetWithConnector(), getLabelOffsetWithConnector()
|
||||
*/
|
||||
double m_labelOffset;
|
||||
/** \brief offset of the box rectangle to the actual data point location [pt], this variant is used when a visible connector is shown (e.g. JKQTPGLSimpleBoxAndLine)
|
||||
*
|
||||
* \see setLabelOffsetWithConnector(), getLabelOffsetWithConnector(), setLabelOffset(), getLabelOffset()
|
||||
*/
|
||||
double m_labelOffsetWithConnector;
|
||||
/** \brief rounding radius of the box rectangle (<=0 -> no rounded rectangle) [pt] */
|
||||
double m_labelBoxRounding;
|
||||
/** \brief padding in x-direction between label and surrounding box [pt] */
|
||||
double m_labelXPadding;
|
||||
/** \brief padding in y-direction between label and surrounding box [pt] */
|
||||
double m_labelYPadding;
|
||||
/** \brief indicates whether to draw a frame around the box */
|
||||
bool m_drawLabelBoxFrame;
|
||||
/** \brief position of the label
|
||||
*
|
||||
* \see JKQTPGraphLabelPosition for details on available options
|
||||
*/
|
||||
JKQTPGraphLabelPosition m_labelPosition;
|
||||
/** \brief type or style of the box surrounding the label text
|
||||
*
|
||||
* \see JKQTPGraphLabelBoxType for details on available options
|
||||
*/
|
||||
JKQTPGraphLabelBoxType m_labelBoxType;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/** \brief display mode for the (axis) labels
|
||||
* \ingroup jkqtplotter_specialgraphs_stylemixins */
|
||||
enum JKQTPGraphLabelConverterType {
|
||||
JKQTPGLCdecimal, /*!< \brief print the numbers in decimal notation, without using exponent characters e.g. \c "0.00123" */
|
||||
JKQTPGLCscientific, /*!< \brief print the numbers in scientific notation, e.g. \c "1.23e-4" */
|
||||
JKQTPGLCexponentCharacter, /*!< \brief print the numbers and show a unit character, i.e. 5μ for \f$ 5\cdot 10^{-6} \f$ , \c 3k for \f$ 3\cdot 10^3 \f$ ... */
|
||||
JKQTPGLCexponent, /*!< \brief show numbers in exponential for, e.g. \f$ 3\cdot 10^5 \f$ ... */
|
||||
JKQTPGLCdatetime, /*!< \brief show numbers as times */
|
||||
|
||||
JKQTPGLDefaultConverter=JKQTPGLCexponent,
|
||||
};
|
||||
|
||||
|
||||
/*! \brief This Mix-In class provides setter/getter methods, and tools for x- and y-value label formatting (i.e. double to string conversion)
|
||||
\ingroup jkqtplotter_specialgraphs_stylemixins
|
||||
|
||||
\see JKQTPXYGraphLabels
|
||||
*/
|
||||
class JKQTPLOTTER_LIB_EXPORT JKQTPXYLabelsGeneratorMixin {
|
||||
#ifndef JKQTPLOTTER_WORKAROUND_QGADGET_BUG
|
||||
Q_GADGET
|
||||
#endif
|
||||
public:
|
||||
|
||||
/** \brief class constructor */
|
||||
explicit JKQTPXYLabelsGeneratorMixin();
|
||||
|
||||
virtual ~JKQTPXYLabelsGeneratorMixin();
|
||||
|
||||
|
||||
|
||||
/** \copydoc m_xDefaultPrecision */
|
||||
int getXDefaultPrecision() const;
|
||||
/** \copydoc m_xDefaultPrecision */
|
||||
void setXDefaultPrecision(int v);
|
||||
/** \copydoc m_yDefaultPrecision */
|
||||
int getYDefaultPrecision() const;
|
||||
/** \copydoc m_yDefaultPrecision */
|
||||
void setYDefaultPrecision(int v);
|
||||
|
||||
/** \copydoc m_xDefaultConverter */
|
||||
JKQTPGraphLabelConverterType getXDefaultConverter() const;
|
||||
/** \copydoc m_xDefaultConverter */
|
||||
void setXDefaultConverter(JKQTPGraphLabelConverterType v);
|
||||
/** \copydoc m_yDefaultConverter */
|
||||
JKQTPGraphLabelConverterType getYDefaultConverter() const;
|
||||
/** \copydoc m_yDefaultConverter */
|
||||
void setYDefaultConverter(JKQTPGraphLabelConverterType v);
|
||||
|
||||
|
||||
/** \copydoc m_xValueLabelFormat */
|
||||
QString getXValueLabelFormat() const;
|
||||
/** \copydoc m_xValueLabelFormat */
|
||||
void setXValueLabelFormat(const QString& v);
|
||||
/** \copydoc m_yValueLabelFormat */
|
||||
QString getYValueLabelFormat() const;
|
||||
/** \copydoc m_yValueLabelFormat */
|
||||
void setYValueLabelFormat(const QString& v);
|
||||
/** \copydoc m_xyValueLabelFormat */
|
||||
QString getXYValueLabelFormat() const;
|
||||
/** \copydoc m_xyValueLabelFormat */
|
||||
void setXYValueLabelFormat(const QString& v);
|
||||
|
||||
|
||||
/** \copydoc m_xBelowIsZero */
|
||||
double getXBelowIsZero() const;
|
||||
/** \copydoc m_xBelowIsZero */
|
||||
void setXBelowIsZero(double v);
|
||||
/** \copydoc m_yBelowIsZero */
|
||||
double getYBelowIsZero() const;
|
||||
/** \copydoc m_yBelowIsZero */
|
||||
void setYBelowIsZero(double v);
|
||||
|
||||
|
||||
/** \copydoc m_xMinNoExponent */
|
||||
double getXMinNoExponent() const;
|
||||
/** \copydoc m_xMinNoExponent */
|
||||
void setXMinNoExponent(double v);
|
||||
/** \copydoc m_yMinNoExponent */
|
||||
double getYMinNoExponent() const;
|
||||
/** \copydoc m_yMinNoExponent */
|
||||
void setYMinNoExponent(double v);
|
||||
|
||||
|
||||
/** \copydoc m_xMaxNoExponent */
|
||||
double getXMaxNoExponent() const;
|
||||
/** \copydoc m_xMaxNoExponent */
|
||||
void setXMaxNoExponent(double v);
|
||||
/** \copydoc m_yMaxNoExponent */
|
||||
double getYMaxNoExponent() const;
|
||||
/** \copydoc m_yMaxNoExponent */
|
||||
void setYMaxNoExponent(double v);
|
||||
|
||||
|
||||
|
||||
/** \copydoc m_xDateTimeFormmat */
|
||||
QString getXDateTimeFormmat() const;
|
||||
/** \copydoc m_xDateTimeFormmat */
|
||||
void setXDateTimeFormmat(const QString& v);
|
||||
/** \copydoc m_yDateTimeFormmat */
|
||||
QString getYDateTimeFormmat() const;
|
||||
/** \copydoc m_yDateTimeFormmat */
|
||||
void setYDateTimeFormmat(const QString& v);
|
||||
|
||||
|
||||
protected:
|
||||
/** \brief default label generator for x-value only */
|
||||
QString generateDefaultXLabel(double x, double y, int index) const;
|
||||
/** \brief default label generator for y-value only */
|
||||
QString generateDefaultYLabel(double x, double y, int index) const;
|
||||
/** \brief default label generator for x- and y-value */
|
||||
QString generateDefaultXYLabel(double x, double y, int index) const;
|
||||
/** \brief converts \a x to a string, using several of the formatting properties set in this class for x-values */
|
||||
QString xValToString(double x) const;
|
||||
/** \brief converts \a y to a string, using several of the formatting properties set in this class for y-values */
|
||||
QString yValToString(double y) const;
|
||||
/** \rief converts \a x to a QString, using the provided options */
|
||||
static QString valToString(double x, JKQTPGraphLabelConverterType m_xDefaultConverter, int m_xDefaultPrecision, double m_xBelowIsZero, double m_xMinNoExponent, double m_xMaxNoExponent, const QString& m_xDateTimeFormat);
|
||||
private:
|
||||
/** \brief format string for the x-label, use \c %1 as placeholder for the numeric value */
|
||||
QString m_xValueLabelFormat;
|
||||
/** \brief format string for the y-label, use \c %1 as placeholder for the numeric value */
|
||||
QString m_yValueLabelFormat;
|
||||
/** \brief format string for the x/y-label, use \c %1 as placeholder for the numeric value of x and \c %2 for y */
|
||||
QString m_xyValueLabelFormat;
|
||||
/** \brief type of number to string conversion for x-values */
|
||||
JKQTPGraphLabelConverterType m_xDefaultConverter;
|
||||
/** \brief type of number to string conversion for y-values */
|
||||
JKQTPGraphLabelConverterType m_yDefaultConverter;
|
||||
/** \brief default precision for x-labels */
|
||||
int m_xDefaultPrecision;
|
||||
/** \brief default precision for x-labels */
|
||||
int m_yDefaultPrecision;
|
||||
/** \brief x-values below this value are treated as exactly 0 */
|
||||
double m_xBelowIsZero;
|
||||
/** \brief y-values below this value are treated as exactly 0 */
|
||||
double m_yBelowIsZero;
|
||||
/** \brief x-values below this value will be shown in exponent notation, above in decimal notation */
|
||||
double m_xMinNoExponent;
|
||||
/** \brief y-values below this value will be shown in exponent notation, above in decimal notation */
|
||||
double m_yMinNoExponent;
|
||||
/** \brief x-values above this value will be shown in exponent notation, below in decimal notation */
|
||||
double m_xMaxNoExponent;
|
||||
/** \brief y-values above this value will be shown in exponent notation, below in decimal notation */
|
||||
double m_yMaxNoExponent;
|
||||
/** \brief format string for datetime -> string conversion of x-values */
|
||||
QString m_xDateTimeFormat;
|
||||
/** \brief format string for datetime -> string conversion of y-value */
|
||||
QString m_yDateTimeFormat;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // jkqtpgraphlabelstylemixin_H
|
@ -34,7 +34,7 @@
|
||||
|
||||
|
||||
/*! \brief Styling Mix-In for Violinplots
|
||||
\ingroup jkqtplotter_basegraphs_stylemixins
|
||||
\ingroup jkqtplotter_specialgraphs_stylemixins
|
||||
|
||||
|
||||
\image html JKQTPViolinplotHorizontalElement_elements.png
|
||||
|
@ -36,13 +36,22 @@ JKQTPGraphLineStyleMixin::JKQTPGraphLineStyleMixin()
|
||||
void JKQTPGraphLineStyleMixin::initLineStyle(JKQTBasePlotter* parent, int &parentPlotStyle, JKQTPPlotStyleType styletype)
|
||||
{
|
||||
if (parent) { // get style settings from parent object
|
||||
if (parentPlotStyle<0) parentPlotStyle=parent->getNextStyle();
|
||||
const JKQTBasePlotter::JKQTPPen pen=parent->getPlotStyle(parentPlotStyle, styletype);
|
||||
m_linePen.setColor(pen.color());
|
||||
m_linePen.setStyle(pen.style());
|
||||
m_lineWidth=pen.widthF();
|
||||
m_highlightingLineColor=getLineColor();
|
||||
m_highlightingLineColor.setAlphaF(0.5);
|
||||
if (styletype==JKQTPPlotStyleType::Annotation) {
|
||||
m_linePen=QPen(parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultLineStyle);
|
||||
m_linePen.setColor(parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultColor);
|
||||
m_linePen.setWidthF(parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultLineWidth);
|
||||
m_lineWidth=m_linePen.widthF();
|
||||
m_highlightingLineColor=getLineColor();
|
||||
m_highlightingLineColor.setAlphaF(0.5);
|
||||
} else {
|
||||
if (parentPlotStyle<0) parentPlotStyle=parent->getNextStyle();
|
||||
const JKQTBasePlotter::JKQTPPen pen=parent->getPlotStyle(parentPlotStyle, styletype);
|
||||
m_linePen.setColor(pen.color());
|
||||
m_linePen.setStyle(pen.style());
|
||||
m_lineWidth=pen.widthF();
|
||||
m_highlightingLineColor=getLineColor();
|
||||
m_highlightingLineColor.setAlphaF(0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,14 +228,22 @@ JKQTPGraphSymbolStyleMixin::JKQTPGraphSymbolStyleMixin()
|
||||
void JKQTPGraphSymbolStyleMixin::initSymbolStyle(JKQTBasePlotter *parent, int& parentPlotStyle, JKQTPPlotStyleType styletype)
|
||||
{
|
||||
if (parent) { // get style settings from parent object
|
||||
if (parentPlotStyle<0) parentPlotStyle=parent->getNextStyle();
|
||||
const JKQTBasePlotter::JKQTPPen pen=parent->getPlotStyle(parentPlotStyle, styletype);
|
||||
m_symbolColor=pen.color();
|
||||
m_symbolSize=pen.symbolSize();
|
||||
m_symbolLineWidth=pen.symbolLineWidthF();
|
||||
m_symbolType=pen.symbol();
|
||||
m_symbolFillColor=pen.symbolFillColor();
|
||||
m_symbolFontName=parent->getDefaultTextFontName();
|
||||
if (styletype==JKQTPPlotStyleType::Annotation) {
|
||||
m_symbolType=parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultSymbol;
|
||||
m_symbolColor=parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultColor;
|
||||
m_symbolLineWidth=parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultSymbolLineWidth;
|
||||
m_symbolSize=parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultSymbolSize;
|
||||
m_symbolFillColor=JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.symbolFillColorDerivationMode, m_symbolColor);
|
||||
} else {
|
||||
if (parentPlotStyle<0) parentPlotStyle=parent->getNextStyle();
|
||||
const JKQTBasePlotter::JKQTPPen pen=parent->getPlotStyle(parentPlotStyle, styletype);
|
||||
m_symbolColor=pen.color();
|
||||
m_symbolSize=pen.symbolSize();
|
||||
m_symbolLineWidth=pen.symbolLineWidthF();
|
||||
m_symbolType=pen.symbol();
|
||||
m_symbolFillColor=pen.symbolFillColor();
|
||||
m_symbolFontName=parent->getDefaultTextFontName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,10 +412,15 @@ void JKQTPGraphFillStyleMixin::initFillStyleInvertedColor(JKQTPGraphFillStyleMix
|
||||
void JKQTPGraphFillStyleMixin::initFillStyle(JKQTBasePlotter *parent, int &parentPlotStyle, JKQTPPlotStyleType styletype)
|
||||
{
|
||||
if (parent) { // get style settings from parent object
|
||||
if (parentPlotStyle<0) parentPlotStyle=parent->getNextStyle();
|
||||
const JKQTBasePlotter::JKQTPPen pen=parent->getPlotStyle(parentPlotStyle, styletype);
|
||||
m_fillColor=pen.fillColor();
|
||||
m_fillBrush=pen.fillStyle().brush(m_fillColor);
|
||||
if (styletype==JKQTPPlotStyleType::Annotation) {
|
||||
m_fillColor=JKQTPGetDerivedColor(parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.fillColorDerivationMode, parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultColor);
|
||||
m_fillBrush=parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultFillStyle.brush(m_fillColor);
|
||||
} else {
|
||||
if (parentPlotStyle<0) parentPlotStyle=parent->getNextStyle();
|
||||
const JKQTBasePlotter::JKQTPPen pen=parent->getPlotStyle(parentPlotStyle, styletype);
|
||||
m_fillColor=pen.fillColor();
|
||||
m_fillBrush=pen.fillStyle().brush(m_fillColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -537,10 +559,14 @@ JKQTPGraphTextStyleMixin::JKQTPGraphTextStyleMixin(JKQTBasePlotter *parent)
|
||||
|
||||
void JKQTPGraphTextStyleMixin::initTextStyle(JKQTBasePlotter *parent, int &/*parentPlotStyle*/, JKQTPPlotStyleType styletype)
|
||||
{
|
||||
if (parent && styletype==JKQTPPlotStyleType::Annotation) { // get style settings from parent object
|
||||
m_textFontSize=parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultFontSize;
|
||||
if (parent) { // get style settings from parent object
|
||||
m_textColor=parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultTextColor;
|
||||
m_textFontName=parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultFontName;
|
||||
if (styletype==JKQTPPlotStyleType::Annotation) {
|
||||
m_textFontSize=parent->getCurrentPlotterStyle().graphsStyle.annotationStyle.defaultFontSize;
|
||||
} else {
|
||||
m_textFontSize=QApplication::font().pointSizeF();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
screenshots/graphlabels.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
screenshots/graphlabels_hor.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
screenshots/graphlabels_hor_small.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
screenshots/graphlabels_small.png
Normal file
After Width: | Height: | Size: 6.3 KiB |