mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 10:01:38 +08:00
JKQTPVectorFieldGraph gained the option to also scale the line width with the vector length/magnitude
This commit is contained in:
parent
4d58448d17
commit
4e29109937
@ -274,7 +274,7 @@ if(JKQtPlotter_BUILD_EXAMPLES)
|
||||
boxplot/JKQTPBoxplotVerticalGraph,JKQTPBoxplotHorizontalGraph/--iteratefunctorsteps--iteratefunctorsteps_suppressinitial--smallscreenshotplot
|
||||
second_axis/JKQTBasePlotter_addSecondaryYAxis,JKQTBasePlotter_addSecondaryXAxis
|
||||
graphlabels/JKQTPGLabelAwayFromXAxis,JKQTPGLabelAwayFromYAxis,JKQTPGLabelTowardsXAxis,JKQTPGLabelTowardsYAxis,JKQTPGLabelAboveData,JKQTPGLabelRightHandSide,JKQTPGLabelBelowData,JKQTPGLabelLeftHandSide,JKQTPGLSimpleBox,JKQTPGLSimpleBoxVertical,JKQTPGLSimpleBoxAndLine,JKQTPGLSimpleBoxAndLineVertical,JKQTPGLSimpleBoxAndLineONLYLABELS,JKQTPGLSimpleBoxAndLineONLYLABELSVertical/--iteratefunctorsteps--smallscreenshotplot
|
||||
vectorfield/JKQTPVectorFieldGraph,JKQTPVectorFieldGraphAnchorBottom,JKQTPVectorFieldGraphAnchorMid,JKQTPVectorFieldGraphAnchorTip,JKQTPVectorFieldGraphAutoscaleLength,JKQTPVectorFieldGraphLengthFromData,JKQTPVectorFieldGraphIgnoreLength/--iteratefunctorsteps
|
||||
vectorfield/JKQTPVectorFieldGraph,JKQTPVectorFieldGraphAnchorBottom,JKQTPVectorFieldGraphAnchorMid,JKQTPVectorFieldGraphAnchorTip,JKQTPVectorFieldGraphAutoscaleLength,JKQTPVectorFieldGraphLengthFromData,JKQTPVectorFieldGraphIgnoreLength,JKQTPVectorFieldGraphIgnoreLengthAutoscaleLineWidthFromLength,JKQTPVectorFieldGraphAutoscaleLengthAutoscaleLineWidthFromLength/--iteratefunctorsteps
|
||||
)
|
||||
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
BIN
doc/images/icon_code_16.png
Normal file
BIN
doc/images/icon_code_16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
@ -53,3 +53,15 @@ Alternatively you can also set
|
||||
which will draw all vectors with the same length. You can scale this length by setting JKQTPVectorFieldGraph::setAutoscaleLengthFactor() ). The result then looks like this:
|
||||
|
||||
![vectorfield](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/doc/images/JKQTPVectorFieldGraphIgnoreLength.png)
|
||||
|
||||
|
||||
Finally it is also possibly to scale the vector's line width with its length:
|
||||
|
||||
```.cpp
|
||||
graph1->setVectorLengthMode(JKQTPVectorFieldGraph::AutoscaleLength);
|
||||
graph1->setVectorLineWidthMode(JKQTPVectorFieldGraph::AutoscaleLineWidthFromLength);
|
||||
```
|
||||
|
||||
This will result in a plot like this:
|
||||
|
||||
![vectorfield](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/doc/images/JKQTPVectorFieldGraphAutoscaleLengthAutoscaleLineWidthFromLength.png)
|
||||
|
@ -61,9 +61,9 @@ int main(int argc, char* argv[])
|
||||
plot.resize(400/plot.devicePixelRatioF(),430/plot.devicePixelRatioF());
|
||||
|
||||
|
||||
|
||||
JKQTPXYScatterGraph* g2;
|
||||
app.addExportStepFunctor([&](){
|
||||
JKQTPXYScatterGraph* g2=new JKQTPXYScatterGraph(&plot);
|
||||
g2=new JKQTPXYScatterGraph(&plot);
|
||||
g2->setXYColumns(columnXY);
|
||||
g2->setTitle("anchor points");
|
||||
g2->setSymbolSize(5);
|
||||
@ -97,5 +97,23 @@ int main(int argc, char* argv[])
|
||||
plot.redrawPlot();
|
||||
});
|
||||
|
||||
app.addExportStepFunctor([&](){
|
||||
g2->setVisible(false);
|
||||
graph1->setAnchorPoint(JKQTPVectorFieldGraph::AnchorBottom);
|
||||
graph1->setVectorLengthMode(JKQTPVectorFieldGraph::IgnoreLength);
|
||||
graph1->setVectorLineWidthMode(JKQTPVectorFieldGraph::AutoscaleLineWidthFromLength);
|
||||
graph1->setLineWidth(4);
|
||||
plot.redrawPlot();
|
||||
});
|
||||
|
||||
app.addExportStepFunctor([&](){
|
||||
g2->setVisible(false);
|
||||
graph1->setAnchorPoint(JKQTPVectorFieldGraph::AnchorBottom);
|
||||
graph1->setVectorLengthMode(JKQTPVectorFieldGraph::AutoscaleLength);
|
||||
graph1->setVectorLineWidthMode(JKQTPVectorFieldGraph::AutoscaleLineWidthFromLength);
|
||||
graph1->setLineWidth(4);
|
||||
plot.redrawPlot();
|
||||
});
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
#include "jkqtcommon/jkqtpdrawingtools.h"
|
||||
#include "jkqtmath/jkqtpstatisticstools.h"
|
||||
#include "jkqtmath/jkqtpstatbasics.h"
|
||||
#include "jkqtplotter/jkqtptools.h"
|
||||
|
||||
#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
|
||||
@ -37,7 +37,9 @@ JKQTPVectorFieldGraph::JKQTPVectorFieldGraph(JKQTBasePlotter *parent):
|
||||
m_vectorLengthMode(AutoscaleLength),
|
||||
m_autoscaleLengthFactor(0.8),
|
||||
m_lengthScaleFactor(1.0),
|
||||
m_anchorPoint(AnchorBottom)
|
||||
m_anchorPoint(AnchorBottom),
|
||||
m_vectorLineWidthMode(DefaultVectorLineWidth),
|
||||
m_minLineWidth(0.001)
|
||||
{
|
||||
initDecoratedLineStyle(parent, parentPlotStyle, JKQTPPlotStyleType::Default);
|
||||
setTailDecoratorStyle(JKQTPNoDecorator);
|
||||
@ -65,6 +67,7 @@ void JKQTPVectorFieldGraph::draw(JKQTPEnhancedPainter &painter)
|
||||
{
|
||||
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
||||
const QPen p=getLinePen(painter, parent);
|
||||
const double lw=getLineWidth();
|
||||
painter.setPen(p);
|
||||
painter.setBrush(p.color());
|
||||
|
||||
@ -72,6 +75,7 @@ void JKQTPVectorFieldGraph::draw(JKQTPEnhancedPainter &painter)
|
||||
int imin=0;
|
||||
double scale=1;
|
||||
if (getIndexRange(imin, imax)) {
|
||||
double minVecLen=0, maxVecLen=0;
|
||||
// first determine (auto-scale) factor
|
||||
if (m_vectorLengthMode==AutoscaleLength || m_vectorLengthMode==IgnoreLength) {
|
||||
double avgVecLength=0;
|
||||
@ -91,11 +95,14 @@ void JKQTPVectorFieldGraph::draw(JKQTPEnhancedPainter &painter)
|
||||
if (NDatapoints==0) {
|
||||
xmin=xmax=xv;
|
||||
ymin=ymax=yv;
|
||||
minVecLen=maxVecLen=l;
|
||||
} else {
|
||||
xmin=qMin(xmin,xv);
|
||||
xmax=qMax(xmax,xv);
|
||||
ymin=qMin(ymin,yv);
|
||||
ymax=qMax(ymax,yv);
|
||||
minVecLen=qMin(minVecLen,l);
|
||||
maxVecLen=qMax(maxVecLen,l);
|
||||
}
|
||||
NDatapoints++;
|
||||
}
|
||||
@ -117,15 +124,15 @@ void JKQTPVectorFieldGraph::draw(JKQTPEnhancedPainter &painter)
|
||||
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);
|
||||
const QPointF vecv=[&]() {
|
||||
QPointF vec=getVectorDxDy(i);
|
||||
const QPointF vec_orig=getVectorDxDy(i);
|
||||
const QPointF vecv=[&](QPointF vec) {
|
||||
if (m_vectorLengthMode==IgnoreLength) {
|
||||
const double veclen=sqrt(jkqtp_sqr(vec.x())+jkqtp_sqr(vec.y()));
|
||||
if (qFuzzyIsNull(veclen)) vec=QPointF(0,0);
|
||||
else vec/=veclen; // normalize vector
|
||||
}
|
||||
return vec;
|
||||
}();
|
||||
}(vec_orig);
|
||||
const QLineF l=[&]() {
|
||||
switch (m_anchorPoint) {
|
||||
case AnchorBottom: return QLineF(x,y,transformX(xv+scale*vecv.x()),transformY(yv+scale*vecv.y()));
|
||||
@ -135,7 +142,16 @@ void JKQTPVectorFieldGraph::draw(JKQTPEnhancedPainter &painter)
|
||||
return QLineF(JKQTP_NAN,JKQTP_NAN,JKQTP_NAN,JKQTP_NAN);
|
||||
}();
|
||||
if (JKQTPIsOKFloat(l) && l.length()>0) {
|
||||
JKQTPPlotDecoratedLine(painter,l, getTailDecoratorStyle(), calcTailDecoratorSize(p.widthF()), getHeadDecoratorStyle(), calcHeadDecoratorSize(p.widthF()));
|
||||
double actualLW=p.widthF();
|
||||
if (m_vectorLineWidthMode==AutoscaleLineWidthFromLength) {
|
||||
const double vec_origlen=sqrt(jkqtp_sqr(vec_orig.x())+jkqtp_sqr(vec_orig.y()));
|
||||
QPen plw=p;
|
||||
plw.setWidthF(m_minLineWidth+(vec_origlen-minVecLen)/(maxVecLen-minVecLen)*(lw-m_minLineWidth));
|
||||
painter.setPen(plw);
|
||||
actualLW=plw.widthF();
|
||||
}
|
||||
|
||||
JKQTPPlotDecoratedLine(painter,l, getTailDecoratorStyle(), calcTailDecoratorSize(actualLW), getHeadDecoratorStyle(), calcHeadDecoratorSize(actualLW));
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,3 +214,23 @@ void JKQTPVectorFieldGraph::setAnchorPoint(VectorAnchorPoint newAnchorPoint)
|
||||
{
|
||||
m_anchorPoint = newAnchorPoint;
|
||||
}
|
||||
|
||||
void JKQTPVectorFieldGraph::setVectorLineWidthMode(VectorLineWidthMode m)
|
||||
{
|
||||
m_vectorLineWidthMode=m;
|
||||
}
|
||||
|
||||
JKQTPVectorFieldGraph::VectorLineWidthMode JKQTPVectorFieldGraph::getVectorLineWidthMode() const
|
||||
{
|
||||
return m_vectorLineWidthMode;
|
||||
}
|
||||
|
||||
void JKQTPVectorFieldGraph::setMinLineWidth(double lw)
|
||||
{
|
||||
m_minLineWidth=lw;
|
||||
}
|
||||
|
||||
double JKQTPVectorFieldGraph::getMinLineWIdth() const
|
||||
{
|
||||
return m_minLineWidth;
|
||||
}
|
||||
|
@ -83,6 +83,11 @@ class JKQTPDatastore;
|
||||
VectorLengthMode.
|
||||
3. By default, vector start at \c (x,y). But you can also make them be centered around or
|
||||
point to \c (x,y) . This can be set by setAnchorPoint().
|
||||
4. Using setVectorLineWidthMode(JKQTPVectorFieldGraph::AutoscaleLineWidthFromLength) you can also
|
||||
scale the line width of each vector by the vector's length. This sometimes gives an easier to read
|
||||
representation of the vector properties, especially if combined with
|
||||
setVectorLengthMode(JKQTPVectorFieldGraph::IgnoreLength) :
|
||||
\image html JKQTPVectorFieldGraphIgnoreLengthAutoscaleLineWidthFromLength.png
|
||||
.
|
||||
|
||||
\see \ref JKQTPlotterVectorFieldExample , JKQTPGraphDecoratedLineStyleMixin , JKQTPXYAndVectorGraph
|
||||
@ -110,6 +115,15 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPVectorFieldGraph: public JKQTPXYAndVectorGraph
|
||||
};
|
||||
Q_ENUM(VectorLengthMode)
|
||||
|
||||
/** \brief describes how the line width scales with the vector properties (or not) */
|
||||
enum VectorLineWidthMode {
|
||||
DefaultVectorLineWidth, //!< \brief line width is equal to JKQTPGraphLineStyleMixin::getLineWidth() for all vectors \image html JKQTPVectorFieldGraphIgnoreLength.png
|
||||
AutoscaleLineWidthFromLength, //!< \brief line width is determined from the vector length. The maximum line width is given by JKQTPGraphLineStyleMixin::getLineWidth() and the minim line width by getMinLineWidth() \image html JKQTPVectorFieldGraphAutoscaleLengthAutoscaleLineWidthFromLength.png
|
||||
|
||||
|
||||
};
|
||||
Q_ENUM(VectorLineWidthMode)
|
||||
|
||||
/** \brief class constructor */
|
||||
explicit JKQTPVectorFieldGraph(JKQTBasePlotter* parent=nullptr);
|
||||
/** \brief class constructor */
|
||||
@ -143,10 +157,22 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPVectorFieldGraph: public JKQTPXYAndVectorGraph
|
||||
/** \copydoc m_anchorPoint */
|
||||
void setAnchorPoint(VectorAnchorPoint newAnchorPoint);
|
||||
|
||||
|
||||
/** \copydoc m_vectorLineWidthMode */
|
||||
void setVectorLineWidthMode(VectorLineWidthMode m);
|
||||
/** \copydoc m_vectorLineWidthMode */
|
||||
VectorLineWidthMode getVectorLineWidthMode() const;
|
||||
/** \copydoc m_minLineWidth */
|
||||
void setMinLineWidth(double lw);
|
||||
/** \copydoc m_minLineWidth */
|
||||
double getMinLineWIdth() const;
|
||||
|
||||
Q_PROPERTY(VectorLengthMode vectorLengthMode READ getVectorLengthMode WRITE setVectorLengthMode )
|
||||
Q_PROPERTY(bool autoscaleLengthFactor READ getAutoscaleLengthFactor WRITE setAutoscaleLengthFactor )
|
||||
Q_PROPERTY(double lengthScaleFactor READ getLengthScaleFactor WRITE setLengthScaleFactor )
|
||||
Q_PROPERTY(VectorAnchorPoint anchorPoint READ getAnchorPoint WRITE setAnchorPoint )
|
||||
Q_PROPERTY(double minLineWidth READ getMinLineWIdth WRITE setMinLineWidth )
|
||||
Q_PROPERTY(VectorLineWidthMode vectorLineWidthMode READ getVectorLineWidthMode WRITE setVectorLineWidthMode )
|
||||
protected:
|
||||
private:
|
||||
/** \brief indicates how the length of the drawn vectors are determined from the data
|
||||
@ -163,7 +189,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPVectorFieldGraph: public JKQTPXYAndVectorGraph
|
||||
* \image html JKQTPVectorFieldGraphIgnoreLength.png
|
||||
* .
|
||||
*
|
||||
* \see VectorLengthMode, setVectorLengthMode(), getVectorLengthMode(), m_autoscaleFactor, m_autoscaleLengthFactor
|
||||
* \see VectorLengthMode, setVectorLengthMode(), getVectorLengthMode(), m_lengthScaleFactor, m_autoscaleLengthFactor
|
||||
*/
|
||||
VectorLengthMode m_vectorLengthMode;
|
||||
/** \brief a scaling factor that can be used to modify the result of the autoscaling algorithm (m_vectorLengthMode \c ==AutoscaleLength)
|
||||
@ -179,9 +205,21 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPVectorFieldGraph: public JKQTPXYAndVectorGraph
|
||||
double m_lengthScaleFactor;
|
||||
/** \brief defines where the vector is anchored
|
||||
*
|
||||
* \see VectorAnchorPoint
|
||||
* \see VectorAnchorPoint, setAnchorPoint(), getAnchorPoint()
|
||||
*/
|
||||
VectorAnchorPoint m_anchorPoint;
|
||||
/** \brief determines how the line width of the vectors is derived.
|
||||
*
|
||||
* \note the available options are described with VectorLineWidthMode
|
||||
*
|
||||
* \see setVectorLineWidthMode(), getVectorLineWidthMode(), VectorLineWidthMode, m_minLineWidth
|
||||
*/
|
||||
VectorLineWidthMode m_vectorLineWidthMode;
|
||||
/** \brief minimum line-width in pt, used for some modes of m_vectorLineWidthMode
|
||||
*
|
||||
* \see setMinLineWidth(), getMinLineWidth(), m_vectorLineWidthMode
|
||||
*/
|
||||
double m_minLineWidth;
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user