mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-09 23:16:00 -06:00
#8676 QtChart : Create curve legend widget for multiplot
This commit is contained in:
parent
f45637b7f0
commit
696c6a15fa
@ -30,6 +30,8 @@
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include "qwt_legend_data.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
@ -289,6 +291,14 @@ void RimPlot::handleDroppedObjects( const std::vector<caf::PdmObjectHandle*>& ob
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimPlotCurve*> RimPlot::visibleCurvesForLegend()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -35,6 +35,7 @@ class QWheelEvent;
|
||||
class RiuPlotWidget;
|
||||
class RiuPlotCurve;
|
||||
class RiuPlotItem;
|
||||
class RimPlotCurve;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -101,6 +102,8 @@ public:
|
||||
virtual caf::PdmObject* findPdmObjectFromPlotCurve( const RiuPlotCurve* curve ) const;
|
||||
virtual void handleDroppedObjects( const std::vector<caf::PdmObjectHandle*>& objects );
|
||||
|
||||
virtual std::vector<RimPlotCurve*> visibleCurvesForLegend();
|
||||
|
||||
protected:
|
||||
virtual RiuPlotWidget* doCreatePlotViewWidget( QWidget* parent ) = 0;
|
||||
|
||||
|
@ -1789,6 +1789,34 @@ RimPlotAxisProperties* RimSummaryPlot::addNewAxisProperties( RiuPlotAxis plotAxi
|
||||
return axisProperties;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimPlotCurve*> RimSummaryPlot::visibleCurvesForLegend()
|
||||
{
|
||||
std::vector<RimPlotCurve*> curves;
|
||||
|
||||
for ( auto c : summaryCurves() )
|
||||
{
|
||||
if ( !c->isCurveVisible() ) continue;
|
||||
if ( !c->showInLegend() ) continue;
|
||||
curves.push_back( c );
|
||||
}
|
||||
|
||||
for ( auto curveSet : curveSets() )
|
||||
{
|
||||
if ( !curveSet->isCurvesVisible() ) continue;
|
||||
if ( curveSet->colorMode() == RimEnsembleCurveSetColorManager::ColorMode::SINGLE_COLOR )
|
||||
{
|
||||
auto curveSetCurves = curveSet->curves();
|
||||
|
||||
if ( !curveSetCurves.empty() ) curves.push_back( curveSetCurves.front() );
|
||||
}
|
||||
}
|
||||
|
||||
return curves;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -199,6 +199,8 @@ public:
|
||||
|
||||
RimPlotAxisProperties* addNewAxisProperties( RiaDefines::PlotAxis, const QString& name );
|
||||
|
||||
std::vector<RimPlotCurve*> visibleCurvesForLegend() override;
|
||||
|
||||
public:
|
||||
// RimViewWindow overrides
|
||||
void deleteViewWidget() override;
|
||||
|
@ -29,13 +29,16 @@
|
||||
|
||||
#include "RimContextCommandBuilder.h"
|
||||
#include "RimMultiPlot.h"
|
||||
#include "RimPlotCurve.h"
|
||||
#include "RimWellLogTrack.h"
|
||||
|
||||
#include "RiuMainWindow.h"
|
||||
#include "RiuPlotMainWindow.h"
|
||||
#include "RiuPlotObjectPicker.h"
|
||||
#include "RiuPlotWidget.h"
|
||||
#include "RiuQtChartsPlotWidget.h"
|
||||
#include "RiuQwtPlotLegend.h"
|
||||
#include "RiuQwtPlotTools.h"
|
||||
#include "RiuQwtPlotWidget.h"
|
||||
|
||||
#include "cafCmdFeatureMenuBuilder.h"
|
||||
@ -176,6 +179,14 @@ void RiuMultiPlotPage::insertPlot( RiuPlotWidget* plotWidget, size_t index )
|
||||
SIGNAL( legendDataChanged( const QVariant&, const QList<QwtLegendData>& ) ),
|
||||
SLOT( updateLegend( const QVariant&, const QList<QwtLegendData>& ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
auto qtchartPlotWidget = dynamic_cast<RiuQtChartsPlotWidget*>( plotWidget );
|
||||
legend->connect( qtchartPlotWidget,
|
||||
SIGNAL( legendDataChanged( const QList<QwtLegendData>& ) ),
|
||||
SLOT( updateLegend( const QList<QwtLegendData>& ) ) );
|
||||
}
|
||||
|
||||
QObject::connect( legend, SIGNAL( legendUpdated() ), this, SLOT( onLegendUpdated() ) );
|
||||
|
||||
legend->contentsWidget()->layout()->setAlignment( Qt::AlignBottom | Qt::AlignHCenter );
|
||||
|
@ -276,40 +276,48 @@ void RiuQtChartsPlotCurve::setSamplesInPlot( const std::vector<double>& xValues,
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQtChartsPlotCurve::updateScatterSeries()
|
||||
{
|
||||
if ( !scatterSeries() ) return;
|
||||
|
||||
double minX = std::numeric_limits<double>::max();
|
||||
double maxX = -std::numeric_limits<double>::max();
|
||||
|
||||
QVector<QPointF> points = lineSeries()->pointsVector();
|
||||
QVector<QPointF> points;
|
||||
|
||||
auto axes = lineSeries()->attachedAxes();
|
||||
bool foundAxis = false;
|
||||
for ( auto axis : axes )
|
||||
if ( lineSeries() )
|
||||
{
|
||||
if ( axis->orientation() == Qt::Orientation::Horizontal )
|
||||
points = lineSeries()->pointsVector();
|
||||
|
||||
bool foundAxis = false;
|
||||
|
||||
auto axes = lineSeries()->attachedAxes();
|
||||
for ( auto axis : axes )
|
||||
{
|
||||
QtCharts::QValueAxis* valueAxis = dynamic_cast<QtCharts::QValueAxis*>( axis );
|
||||
QtCharts::QDateTimeAxis* dateTimeAxis = dynamic_cast<QtCharts::QDateTimeAxis*>( axis );
|
||||
if ( valueAxis )
|
||||
if ( axis->orientation() == Qt::Orientation::Horizontal )
|
||||
{
|
||||
minX = valueAxis->min();
|
||||
maxX = valueAxis->max();
|
||||
foundAxis = true;
|
||||
}
|
||||
else if ( dateTimeAxis )
|
||||
{
|
||||
minX = dateTimeAxis->min().toMSecsSinceEpoch();
|
||||
maxX = dateTimeAxis->max().toMSecsSinceEpoch();
|
||||
foundAxis = true;
|
||||
QtCharts::QValueAxis* valueAxis = dynamic_cast<QtCharts::QValueAxis*>( axis );
|
||||
QtCharts::QDateTimeAxis* dateTimeAxis = dynamic_cast<QtCharts::QDateTimeAxis*>( axis );
|
||||
if ( valueAxis )
|
||||
{
|
||||
minX = valueAxis->min();
|
||||
maxX = valueAxis->max();
|
||||
foundAxis = true;
|
||||
}
|
||||
else if ( dateTimeAxis )
|
||||
{
|
||||
minX = dateTimeAxis->min().toMSecsSinceEpoch();
|
||||
maxX = dateTimeAxis->max().toMSecsSinceEpoch();
|
||||
foundAxis = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !foundAxis )
|
||||
{
|
||||
for ( auto p : points )
|
||||
if ( !foundAxis )
|
||||
{
|
||||
minX = std::min( minX, p.x() );
|
||||
maxX = std::max( maxX, p.x() );
|
||||
for ( auto p : points )
|
||||
{
|
||||
minX = std::min( minX, p.x() );
|
||||
maxX = std::max( maxX, p.x() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,6 +138,62 @@ void RiuQtChartsPlotCurveSymbol::applyToScatterSeries( QtCharts::QScatterSeries*
|
||||
series->setColor( m_color );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QImage RiuQtChartsPlotCurveSymbol::image() const
|
||||
{
|
||||
if ( m_style == PointSymbolEnum::SYMBOL_NONE )
|
||||
{
|
||||
return QImage();
|
||||
}
|
||||
|
||||
if ( m_style == PointSymbolEnum::SYMBOL_RECT )
|
||||
{
|
||||
return createRectImage();
|
||||
}
|
||||
else if ( m_style == PointSymbolEnum::SYMBOL_ELLIPSE )
|
||||
{
|
||||
return createEllipseImage();
|
||||
}
|
||||
else if ( m_style == PointSymbolEnum::SYMBOL_CROSS )
|
||||
{
|
||||
return createCrossImage();
|
||||
}
|
||||
else if ( m_style == PointSymbolEnum::SYMBOL_XCROSS )
|
||||
{
|
||||
return createXCrossImage();
|
||||
}
|
||||
else if ( m_style == PointSymbolEnum::SYMBOL_DIAMOND )
|
||||
{
|
||||
return createDiamondImage();
|
||||
}
|
||||
else if ( m_style == PointSymbolEnum::SYMBOL_HEXAGON )
|
||||
{
|
||||
return createHexagonImage();
|
||||
}
|
||||
else if ( m_style == PointSymbolEnum::SYMBOL_STAR1 )
|
||||
{
|
||||
return createStar1Image();
|
||||
}
|
||||
else if ( m_style == PointSymbolEnum::SYMBOL_STAR1 )
|
||||
{
|
||||
return createStar1Image();
|
||||
}
|
||||
else if ( m_style == PointSymbolEnum::SYMBOL_STAR2 )
|
||||
{
|
||||
return createStar2Image();
|
||||
}
|
||||
else if ( m_style == PointSymbolEnum::SYMBOL_TRIANGLE || m_style == PointSymbolEnum::SYMBOL_UP_TRIANGLE ||
|
||||
m_style == PointSymbolEnum::SYMBOL_DOWN_TRIANGLE || m_style == PointSymbolEnum::SYMBOL_LEFT_TRIANGLE ||
|
||||
m_style == PointSymbolEnum::SYMBOL_RIGHT_TRIANGLE )
|
||||
{
|
||||
return createTriangleImage( m_style );
|
||||
}
|
||||
|
||||
return QImage();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -60,6 +60,8 @@ public:
|
||||
|
||||
void applyToScatterSeries( QtCharts::QScatterSeries* series ) const;
|
||||
|
||||
QImage image() const;
|
||||
|
||||
private:
|
||||
QImage createTriangleImage( RiuPlotCurveSymbol::PointSymbolEnum symbolStyle ) const;
|
||||
QImage createRectImage() const;
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "RiuQtChartsPlotCurve.h"
|
||||
#include "RiuQtChartsToolTip.h"
|
||||
#include "RiuQwtDateScaleWrapper.h"
|
||||
#include "RiuQwtPlotTools.h"
|
||||
|
||||
#include "caf.h"
|
||||
#include "cafAssert.h"
|
||||
@ -333,6 +334,7 @@ void RiuQtChartsPlotWidget::clearLegend()
|
||||
{
|
||||
QLegend* legend = qtChart()->legend();
|
||||
legend->detachFromChart();
|
||||
legend->hide();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -496,6 +498,11 @@ void RiuQtChartsPlotWidget::updateLayout()
|
||||
void RiuQtChartsPlotWidget::updateLegend()
|
||||
{
|
||||
qtChart()->legend()->update();
|
||||
|
||||
auto curves = plotDefinition()->visibleCurvesForLegend();
|
||||
|
||||
auto legendData = RiuQwtPlotTools::createLegendData( curves );
|
||||
emit legendDataChanged( legendData );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
#include "qwt_legend_data.h"
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
#include <set>
|
||||
@ -219,6 +221,7 @@ protected:
|
||||
|
||||
signals:
|
||||
void plotZoomed();
|
||||
void legendDataChanged( const QList<QwtLegendData>& data );
|
||||
|
||||
private slots:
|
||||
void axisRangeChanged();
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "RiuQwtPlotLegend.h"
|
||||
|
||||
#include "qwt_dyngrid_layout.h"
|
||||
#include "qwt_legend_label.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QResizeEvent>
|
||||
@ -109,3 +110,28 @@ void RiuQwtPlotLegend::updateLegend( const QVariant& variant, const QList<QwtLeg
|
||||
QwtLegend::updateLegend( variant, legendItems );
|
||||
emit legendUpdated();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQwtPlotLegend::updateLegend( const QList<QwtLegendData>& legendData )
|
||||
{
|
||||
// Delete all existing widgets
|
||||
deleteAll();
|
||||
|
||||
// Create legend widgets based on legendData
|
||||
updateLegend( QVariant(), legendData );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQwtPlotLegend::deleteAll()
|
||||
{
|
||||
auto widgets = contentsWidget()->findChildren<QwtLegendLabel*>();
|
||||
for ( auto w : widgets )
|
||||
{
|
||||
w->hide();
|
||||
w->deleteLater();
|
||||
}
|
||||
}
|
||||
|
@ -28,10 +28,14 @@ public:
|
||||
QSize sizeHint() const override;
|
||||
public slots:
|
||||
void updateLegend( const QVariant&, const QList<QwtLegendData>& ) override;
|
||||
void updateLegend( const QList<QwtLegendData>& );
|
||||
|
||||
signals:
|
||||
void legendUpdated();
|
||||
|
||||
private:
|
||||
void deleteAll();
|
||||
|
||||
private:
|
||||
int m_columnCount;
|
||||
};
|
||||
|
@ -17,14 +17,21 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RiuQwtPlotTools.h"
|
||||
|
||||
#include "RiuGuiTheme.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaColorTools.h"
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaQDateTimeTools.h"
|
||||
|
||||
#include "RimPlotCurve.h"
|
||||
|
||||
#include "RiuGuiTheme.h"
|
||||
#include "RiuQtChartsPlotCurveSymbol.h"
|
||||
#include "RiuQwtPlotLegend.h"
|
||||
|
||||
#include "qwt_date_scale_draw.h"
|
||||
#include "qwt_date_scale_engine.h"
|
||||
#include "qwt_graphic.h"
|
||||
#include "qwt_painter.h"
|
||||
#include "qwt_plot.h"
|
||||
#include "qwt_plot_grid.h"
|
||||
#include "qwt_plot_layout.h"
|
||||
@ -32,6 +39,7 @@
|
||||
#include "qwt_scale_widget.h"
|
||||
|
||||
#include <QRegExp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -266,3 +274,71 @@ RiaDefines::PlotAxis RiuQwtPlotTools::fromQwtPlotAxis( QwtPlot::Axis axis )
|
||||
|
||||
return RiaDefines::PlotAxis::PLOT_AXIS_TOP;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuQwtPlotTools::updateLegendData( RiuQwtPlotLegend* legend, const std::vector<RimPlotCurve*>& curves )
|
||||
{
|
||||
QList<QwtLegendData> legendDataList = createLegendData( curves );
|
||||
|
||||
legend->updateLegend( QVariant(), legendDataList );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<QwtLegendData> RiuQwtPlotTools::createLegendData( const std::vector<RimPlotCurve*>& curves )
|
||||
{
|
||||
QList<QwtLegendData> legendDataList;
|
||||
|
||||
for ( auto c : curves )
|
||||
{
|
||||
QwtLegendData test;
|
||||
test.setValue( QwtLegendData::Role::TitleRole, c->curveName() );
|
||||
|
||||
c->updateUiIconFromPlotSymbol();
|
||||
auto icon = c->uiIcon();
|
||||
auto size = icon->availableSizes().first();
|
||||
// see QwtPlotCurve::legendIcon
|
||||
|
||||
QwtGraphic graphic;
|
||||
{
|
||||
graphic.setDefaultSize( size );
|
||||
graphic.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
|
||||
|
||||
QPainter painter( &graphic );
|
||||
painter.setRenderHint( QPainter::Antialiasing );
|
||||
|
||||
{
|
||||
QPen pn;
|
||||
pn.setCapStyle( Qt::FlatCap );
|
||||
pn.setColor( RiaColorTools::toQColor( c->color() ) );
|
||||
|
||||
painter.setPen( pn );
|
||||
|
||||
const double y = 0.5 * size.height();
|
||||
QwtPainter::drawLine( &painter, 0.0, y, size.width(), y );
|
||||
}
|
||||
|
||||
if ( c->symbol() != RiuQtChartsPlotCurveSymbol::SYMBOL_NONE )
|
||||
{
|
||||
RiuQtChartsPlotCurveSymbol symbol( c->symbol() );
|
||||
symbol.setSize( size.height() / 2, size.height() / 2 );
|
||||
symbol.setColor( RiaColorTools::toQColor( c->color() ) );
|
||||
|
||||
auto image = symbol.image();
|
||||
|
||||
QPoint p( size.width() / 4, size.height() / 4 );
|
||||
painter.drawImage( p, image );
|
||||
}
|
||||
}
|
||||
|
||||
QVariant v = QVariant::fromValue( graphic );
|
||||
test.setValue( QwtLegendData::Role::IconRole, v );
|
||||
|
||||
legendDataList.push_back( test );
|
||||
}
|
||||
|
||||
return legendDataList;
|
||||
}
|
||||
|
@ -24,6 +24,9 @@
|
||||
#include <qwt_plot.h>
|
||||
#include <qwt_plot_shapeitem.h>
|
||||
|
||||
class RiuQwtPlotLegend;
|
||||
class RimPlotCurve;
|
||||
|
||||
class RiuQwtPlotTools
|
||||
{
|
||||
public:
|
||||
@ -61,6 +64,9 @@ public:
|
||||
|
||||
static QwtPlot::Axis toQwtPlotAxis( RiaDefines::PlotAxis );
|
||||
static RiaDefines::PlotAxis fromQwtPlotAxis( QwtPlot::Axis );
|
||||
|
||||
static void updateLegendData( RiuQwtPlotLegend* legend, const std::vector<RimPlotCurve*>& curves );
|
||||
static QList<QwtLegendData> createLegendData( const std::vector<RimPlotCurve*>& curves );
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user