mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 01:51:49 +08:00
- corrected size of internal image buffer --> fixes strange rendering with distortions (especially in text!)
- added missing override declarations - JKQTPlotter::jkqtp_RESIZE_DELAY is thread-safe now (atomic)
This commit is contained in:
parent
4c1668e50d
commit
7eca9f7c8b
@ -31,13 +31,17 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
<li>FIXED: styling was not properly applied to coordinate axes of colorbars outside the plot</li>
|
||||
<li>FIXED issue <a href="https://github.com/jkriege2/JKQtPlotter/pull/73">#73: Symbol thickness differs in actual plot and legend</a>, thanks to <a href="https://github.com/sim186">user:sim186</a></li>
|
||||
<li>FIXED plot-size calculation for filled graphs</li>
|
||||
<li>FIXED issue #98: Signal JKQTPlotter::plotMouseWheelOperated() was called with wrong x/y-position-coordinates, thanks to <a href="https://github.com/fpalazzolo">user:fpalazzolo</a> for reporting this bug<li>
|
||||
<li>FIXED issue #98: Signal JKQTPlotter::plotMouseWheelOperated() was called with wrong x/y-position-coordinates, thanks to <a href="https://github.com/fpalazzolo">user:fpalazzolo</a> for reporting this bug</li>
|
||||
<li>FIXED: first symbol in symbols rotation was never used</li>
|
||||
<li>FIXED: color palettes with few entries (i.e. "step"-palettes) were not applied correctly</li>
|
||||
<li>REORGANIZED: separated line-graphs from jkqtpscatter.h/.cpp into jkqtplines.h/.cpp</li>
|
||||
<li>IMPROVED: QT6-compatibility by removing deprecated warnings</li>
|
||||
<li>IMPROVED/REWORKED: reworked JKQTPErrorPlotstyle and error indicator plotting so error-inidcators can be specified as ORed combination of flags from JKQTPErrorPlotstyleElements, added additional error indicator styles (half-bars, arrows...)</li>
|
||||
<li>IMPROVED/REWORKED: reworked JKQTPCADrawMode and coordinate axis drawing so the draw mide can be specified as ORed combination of flags from JKQTPCADrawModeElements, added flags to draw arrows at the end of the axis line</li>
|
||||
<li>IMPROVED/REWORKED: coordinate axis code was refactored</li>
|
||||
<li>IMPROVED/REWORKED: zomm/pan by mouse-wheel: now there are modes that support zoomin AND panning by trakpad and mouse-wheel simultaneously! This can only be implemented using heuristics, due to the way that Qt handles track-pad events, but the current solution should at least improve the behaviour seen before. Mainly <code>jkqtpmwaZoomByWheelAndTrackpadPan</code> was introduced into <code>JKQTPMouseWheelActions</code> und is set as default mode: Here JKQTPlotter tries to distinguish the QWheelEvent s sent by an actual mouse wheel and a trackpad.</li>
|
||||
<li>IMPROVED/REWORKED: better example graphs in \subpage JKQTPlotterStyling.</li>
|
||||
<li>IMPROVED: documentation of styles: automatized doc image generation.</li>
|
||||
<li>NEW: JKQTPFilledCurveXGraph and JKQTPFilledCurveYGraph can now plot wiggle plots with different fill styles above and below the baseline (feature request <a href="https://github.com/jkriege2/JKQtPlotter/issues/68">#68 Wiggle Plots</a> from <a href="https://github.com/xichaoqiang">user:xichaoqiang</a> </li>
|
||||
<li>NEW/BREAKING CHANGE: data tooltip can now also be shown when "just" moving the mouse (so far this was only possible when dragging the mouse with a button pressed). This also removes JKQtPlotter::getActMouseLeftAsToolTip() and adds JKQtPlotter::getActMouseMoveToolTip() instead! Also the default toolbars and context menus changed!</li>
|
||||
<li>NEW: new "seaborn" style for plots, see \ref jkqtpplotter_styling </li>
|
||||
@ -73,6 +77,8 @@ Changes, compared to \ref page_whatsnew_V4_0_0 "v4.0.0" include:
|
||||
<li>NEW: you can provide a custom draw functor to barcharts to completely customize their look</li>
|
||||
<li>NEW: barcharts and impulse graphs may now draw their baseline as stylable line (default: off)</li>
|
||||
<li>NEW: secondary axes: added functionality to manage additional secondary axes in a JKQTPBasePlotter and to select which x-/y-Axis to use for drawing a JKQTPPlotElement</li>
|
||||
<li>NEW: You can use additional syntax derived from CCS to define colors in style.ini.files (or when using jkqtp_String2QColor() ): You can use full CSS-color syntax with functions <code>"rgb(R,G,B)"</code>, <code>"rgba(...)"</code>, <code>"hsl(...)"</code>, <code>"hsv(...)"</code>, <code>"gray(...)"</code>, <code>"green(...)"</code>, <code>"red(...)"</code>, <code>"blue(...)"</code>.</li>
|
||||
<li>NEW: several new color palettes (especially stepped/categorial palettes), e.g. JKQTPMathImageColorPalette::JKQTPMathImageOkabeIto_STEP, JKQTPMathImageColorPalette::JKQTPMathImageIBMColorBlindSafe, JKQTPMathImageColorPalette::JKQTPMathImageIBMColorBlindSafe_STEP, ...</li>
|
||||
</ul></li>
|
||||
|
||||
<li>JKQTMathText:<ul>
|
||||
|
BIN
doc/images/palettes/palette_jkqtplotterdefault_steps.png
Normal file
BIN
doc/images/palettes/palette_jkqtplotterdefault_steps.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 211 B |
@ -31,7 +31,7 @@
|
||||
#include "jkqtplotter.h"
|
||||
|
||||
|
||||
int JKQTPlotter::jkqtp_RESIZE_DELAY = 100;
|
||||
std::atomic<int> JKQTPlotter::jkqtp_RESIZE_DELAY = 100;
|
||||
|
||||
void JKQTPlotter::setGlobalResizeDelay(int delayMS)
|
||||
{
|
||||
@ -91,9 +91,7 @@ JKQTPlotter::JKQTPlotter(bool datastore_internal, QWidget* parent, JKQTPDatastor
|
||||
connect(plotter, SIGNAL(beforePlotScalingRecalculate()), this, SLOT(intBeforePlotScalingRecalculate()));
|
||||
connect(plotter, SIGNAL(zoomChangedLocally(double, double, double, double, JKQTBasePlotter*)), this, SLOT(pzoomChangedLocally(double, double, double, double, JKQTBasePlotter*)));
|
||||
|
||||
const qreal dpr = devicePixelRatioF();
|
||||
image=QImage(width()*dpr, height()*dpr, QImage::Format_ARGB32);
|
||||
image.setDevicePixelRatio(dpr);
|
||||
image=createImageBuffer();
|
||||
oldImage=image;
|
||||
|
||||
// enable mouse-tracking, so mouseMoved-Events can be caught
|
||||
@ -179,6 +177,35 @@ void JKQTPlotter::fixBasePlotterSettings()
|
||||
}
|
||||
}
|
||||
|
||||
JKQTPlotter::InternalBufferImageType JKQTPlotter::createImageBuffer() const
|
||||
{
|
||||
float scale=1.0;
|
||||
auto img=InternalBufferImageType(getImageBufferSize(&scale));
|
||||
img.setDevicePixelRatio(scale);
|
||||
return img;
|
||||
}
|
||||
|
||||
QSize JKQTPlotter::getImageBufferSize(float* scale_out) const
|
||||
{
|
||||
float imagewidth=width();
|
||||
float imageheight=height()-getPlotYOffset();
|
||||
/*
|
||||
* The following code is to avoid low quality blur pixmap created via
|
||||
* QPainter, sample code is found in QAbstractItemViewPrivate::renderToPixmap method
|
||||
*/
|
||||
qreal scale = 1.0;
|
||||
const QWidget *window = this->window();
|
||||
if (window) {
|
||||
const QWindow *windowHandle = window->windowHandle();
|
||||
if (windowHandle) {
|
||||
scale = windowHandle->devicePixelRatio();
|
||||
}
|
||||
}
|
||||
qDebug()<<"scale="<<scale<<", dprF="<<devicePixelRatioF()<<", dpr="<<devicePixelRatio()<<" widgetsize="<<QSize(width(),height())<<" img:deviceindependensize="<<QSize(imagewidth,imageheight)<<" img.size.raw="<<QSize(width()*scale, height()*scale);
|
||||
if (scale_out) *scale_out=scale;
|
||||
return QSize(imagewidth*scale, imageheight*scale);
|
||||
}
|
||||
|
||||
void JKQTPlotter::updateToolbarActions()
|
||||
{
|
||||
toolbar->clear();
|
||||
@ -195,7 +222,7 @@ void JKQTPlotter::setToolbarIconSize(int value) {
|
||||
toolbar->setIconSize(s);
|
||||
}
|
||||
|
||||
int JKQTPlotter::getToolbarIconSize() {
|
||||
int JKQTPlotter::getToolbarIconSize() const {
|
||||
return plotterStyle.toolbarIconSize;
|
||||
}
|
||||
|
||||
@ -1121,7 +1148,7 @@ bool JKQTPlotter::event(QEvent* event) {
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
int JKQTPlotter::getPlotYOffset() {
|
||||
int JKQTPlotter::getPlotYOffset() const {
|
||||
int plotYOffset=0;
|
||||
if (plotterStyle.displayMousePosition) {
|
||||
plotYOffset=plotYOffset+QFontMetrics(font()).height()+2;
|
||||
@ -1315,14 +1342,12 @@ void JKQTPlotter::paintEvent(QPaintEvent *event){
|
||||
p->drawText(QPointF(plotter->getInternalPlotBorderLeft(), getPlotYOffset()-1), plotterStyle.mousePositionTemplate.arg(mousePosX).arg(mousePosY));
|
||||
}
|
||||
|
||||
int plotImageWidth=width();
|
||||
int plotImageHeight=height();
|
||||
const QSize plotImageSize=getImageBufferSize();
|
||||
|
||||
plotImageHeight=plotImageHeight-getPlotYOffset();
|
||||
if (image.width()!=plotImageWidth || image.height()!=plotImageHeight) {
|
||||
p->drawImage(QRectF(0, getPlotYOffset(), plotImageWidth, plotImageHeight), image);
|
||||
if (image.size() != plotImageSize) {
|
||||
p->drawPixmap(QRect(QPoint(0, getPlotYOffset()), plotImageSize), image);
|
||||
} else {
|
||||
p->drawImage(QPoint(0, getPlotYOffset()), image);
|
||||
p->drawPixmap(QPoint(0, getPlotYOffset()), image);
|
||||
}
|
||||
}
|
||||
delete p;
|
||||
@ -1355,23 +1380,8 @@ void JKQTPlotter::resizeEvent(QResizeEvent *event) {
|
||||
|
||||
void JKQTPlotter::delayedResizeEvent()
|
||||
{
|
||||
qreal dpr = devicePixelRatioF();
|
||||
int plotImageWidth=width() * dpr;
|
||||
int plotImageHeight=height() * dpr;
|
||||
|
||||
plotImageHeight=plotImageHeight-getPlotYOffset();
|
||||
//qDebug()<<"resize: "<<plotImageWidth<<" x "<<plotImageHeight<<std::endl;
|
||||
bool sizeChanged=false;
|
||||
if (plotImageWidth != image.width() || plotImageHeight != image.height()) {
|
||||
|
||||
QImage newImage(QSize(plotImageWidth, plotImageHeight), QImage::Format_ARGB32);
|
||||
newImage.setDevicePixelRatio(dpr);
|
||||
|
||||
image=newImage;
|
||||
sizeChanged=true;
|
||||
}
|
||||
|
||||
if (sizeChanged) {
|
||||
if (getImageBufferSize() != image.size()) {
|
||||
image=createImageBuffer();
|
||||
emit widgetResized(width(), height(), this);
|
||||
redrawPlot();
|
||||
}
|
||||
|
@ -363,11 +363,11 @@ JKQTPLOTTER_LIB_EXPORT void initJKQTPlotterResources();
|
||||
class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/** \brief sets the global resize delay in milliseconds \a delayMS. After calling this function all plots will use the new delay
|
||||
/** \brief sets the global resize delay in milliseconds \a delayMS. After calling this function all plots will use the new delay. This function is thread-safe!
|
||||
*
|
||||
* \see jkqtp_RESIZE_DELAY, setGlobalResizeDelay(), getGlobalResizeDelay(), resizeTimer */
|
||||
static void setGlobalResizeDelay(int delayMS);
|
||||
/** \brief returns the currently set global resize delay in milliseconds \a delayMS.
|
||||
/** \brief returns the currently set global resize delay in milliseconds \a delayMS. This function is thread-safe!
|
||||
*
|
||||
* \see jkqtp_RESIZE_DELAY, setGlobalResizeDelay(), getGlobalResizeDelay(), resizeTimer */
|
||||
static int getGlobalResizeDelay();
|
||||
@ -397,10 +397,12 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
void setToolbarIconSize(int value);
|
||||
|
||||
/** \brief get the width/height of the icons in the toolbar in pt */
|
||||
int getToolbarIconSize();
|
||||
int getToolbarIconSize() const;
|
||||
|
||||
/** \brief returns the class internally used for plotting */
|
||||
JKQTBasePlotter* getPlotter() const { return plotter; }
|
||||
JKQTBasePlotter* getPlotter() { return plotter; }
|
||||
/** \brief returns the class internally used for plotting */
|
||||
const JKQTBasePlotter* getPlotter() const { return plotter; }
|
||||
/** \brief returns the class internally used for plotting */
|
||||
const JKQTBasePlotter* getConstplotter() const { return const_cast<const JKQTBasePlotter*>(plotter); }
|
||||
|
||||
@ -479,10 +481,10 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
void saveSettings(QSettings& settings, const QString& group=QString("plots/")) const;
|
||||
|
||||
/** \brief returns the minimum size of the widget */
|
||||
QSize minimumSizeHint() const;
|
||||
QSize minimumSizeHint() const override;
|
||||
|
||||
/** \brief returns the size of the widget */
|
||||
QSize sizeHint() const;
|
||||
QSize sizeHint() const override;
|
||||
|
||||
/** \brief returns \c true, if the JKQTPlotter::resizeTimer is currently running and the widget is waiting for the resize-event to finish
|
||||
*
|
||||
@ -617,7 +619,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
/** \copydoc JKQTBasePlotter::setEmittingSignalsEnabled() */
|
||||
inline void setEmittingSignalsEnabled(bool sig) { plotter->setEmittingSignalsEnabled(sig); }
|
||||
/** \copydoc JKQTBasePlotter::isEmittingSignalsEnabled() */
|
||||
inline bool isEmittingSignalsEnabled() { return plotter->isEmittingSignalsEnabled(); }
|
||||
inline bool isEmittingSignalsEnabled() const { return plotter->isEmittingSignalsEnabled(); }
|
||||
|
||||
/** \brief returns, whether automatic redrawing the plot is currently activated (e.g. you can deactivate this with setPlotUpdateEnabled() while performing major updates on the plot)
|
||||
*
|
||||
@ -1518,14 +1520,25 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
/** \brief internal list of markers to be drawn by paintUserAction() */
|
||||
QList<MouseDragMarker> mouseDragMarkers;
|
||||
|
||||
typedef QPixmap InternalBufferImageType;
|
||||
|
||||
/** \brief this stores the currently displayed plot */
|
||||
QImage image;
|
||||
InternalBufferImageType image;
|
||||
|
||||
/** \brief this can be used when drawing a zoom rectangle to store an unchanged
|
||||
* copy of the currently displayed image.
|
||||
*/
|
||||
QImage oldImage;
|
||||
InternalBufferImageType oldImage;
|
||||
|
||||
/** \brief constructs a new image for the internal double-buffering
|
||||
* \internal
|
||||
*/
|
||||
InternalBufferImageType createImageBuffer() const;
|
||||
|
||||
/** \brief returns the required size of an image for the internal double-buffering
|
||||
* \internal
|
||||
*/
|
||||
QSize getImageBufferSize(float* scale_out=nullptr) const;
|
||||
|
||||
|
||||
/** \brief use this QMenu instance instead of the standard context menu of this widget
|
||||
@ -1547,7 +1560,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
*
|
||||
* \see registerMouseDoubleClickAction(), deregisterMouseDoubleClickAction()
|
||||
*/
|
||||
void mouseDoubleClickEvent ( QMouseEvent * event );
|
||||
void mouseDoubleClickEvent ( QMouseEvent * event ) override;
|
||||
|
||||
/*! \brief react on key presses.
|
||||
|
||||
@ -1555,7 +1568,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
- ESC stops current zooming/drawing action
|
||||
.
|
||||
*/
|
||||
void keyReleaseEvent(QKeyEvent* event);
|
||||
void keyReleaseEvent(QKeyEvent* event) override;
|
||||
|
||||
/** \brief event handler for a mouse move
|
||||
*
|
||||
@ -1569,7 +1582,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
* \see mousePosX, mousePosY
|
||||
* \see registerMouseWheelAction(), deregisterMouseWheelAction(), registeredMouseWheelActions
|
||||
*/
|
||||
void mouseMoveEvent ( QMouseEvent * event );
|
||||
void mouseMoveEvent ( QMouseEvent * event ) override;
|
||||
|
||||
/** \brief event handler for a mouse down event
|
||||
*
|
||||
@ -1578,13 +1591,13 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
*
|
||||
* \see registerMouseDragAction(), deregisterMouseDragAction(), registeredJKQTPMouseDragActions
|
||||
*/
|
||||
void mousePressEvent ( QMouseEvent * event );
|
||||
void mousePressEvent ( QMouseEvent * event ) override;
|
||||
|
||||
/** \brief event handler for a mouse release event
|
||||
*
|
||||
* this finishes the action, started by mousePressEvent()
|
||||
*/
|
||||
void mouseReleaseEvent ( QMouseEvent * event );
|
||||
void mouseReleaseEvent ( QMouseEvent * event ) override;
|
||||
|
||||
/** \brief event handler for a turn of the mouse wheel
|
||||
*
|
||||
@ -1592,16 +1605,16 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
*
|
||||
* \see registerMouseWheelAction(), deregisterMouseWheelAction(), registeredMouseWheelActions
|
||||
*/
|
||||
void wheelEvent(QWheelEvent * event);
|
||||
void wheelEvent(QWheelEvent * event) override;
|
||||
|
||||
/** \brief this simply paints the stored image to the widget's surface */
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
/** \brief resizes the internal representation (image) of the graphs */
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
/** \brief called, when the mouse leaves the widget, hides the toolbar (if visible) */
|
||||
void leaveEvent ( QEvent * event );
|
||||
void leaveEvent ( QEvent * event ) override;
|
||||
|
||||
|
||||
/** \brief update settings of the toolbar */
|
||||
@ -1614,7 +1627,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
QPointer<JKQTPlotter> masterPlotterY;
|
||||
|
||||
/** \brief calculate the y-axis shift of the plot, so there is space for the potentially displayed mouse position label */
|
||||
int getPlotYOffset();
|
||||
int getPlotYOffset() const;
|
||||
|
||||
/** \brief x-position of the mouse during the last mouseMoveEvent() calls (in plot coordinates) */
|
||||
double mousePosX;
|
||||
@ -1677,7 +1690,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
*
|
||||
* \see jkqtp_RESIZE_DELAY, setGlobalResizeDelay(), getGlobalResizeDelay(), resizeTimer
|
||||
*/
|
||||
static int jkqtp_RESIZE_DELAY;
|
||||
static std::atomic<int> jkqtp_RESIZE_DELAY;
|
||||
|
||||
/** \brief destroys the internal contextMenu and optionally creates a new one
|
||||
*
|
||||
@ -1718,7 +1731,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPlotter: public QWidget {
|
||||
QAction* actMouseLeftAsPanView;
|
||||
|
||||
virtual bool event(QEvent *event) override;
|
||||
protected slots:
|
||||
protected slots:
|
||||
/** \brief while the window is resized, the plot is only redrawn after a restartable delay, implemented by this function and resizeTimer
|
||||
* \internal
|
||||
* \see resizeTimer
|
||||
|
Loading…
Reference in New Issue
Block a user