#5539 Add texts on Bars

This commit is contained in:
Jacob Støren
2020-02-17 10:40:18 +01:00
parent dd114b7928
commit e9f8cf8105
3 changed files with 150 additions and 94 deletions

View File

@@ -322,50 +322,50 @@ void RimAnalysisPlot::onLoadDataAndUpdate()
{ {
RiuGroupedBarChartBuilder chartBuilder( Qt::Horizontal ); RiuGroupedBarChartBuilder chartBuilder( Qt::Horizontal );
chartBuilder.addBarEntry( "T1_The_red_Fox", "", "", std::numeric_limits<double>::infinity(), "R1", 0.4 ); chartBuilder.addBarEntry( "T1_The_red_Fox", "", "", std::numeric_limits<double>::infinity(), "R1", "", 0.4 );
chartBuilder.addBarEntry( "T1_The_red_Fox", "", "", std::numeric_limits<double>::infinity(), "R2", 0.45 ); chartBuilder.addBarEntry( "T1_The_red_Fox", "", "", std::numeric_limits<double>::infinity(), "R2", "", 0.45 );
chartBuilder.addBarEntry( "T1_The_red_Fox", "W1", "", std::numeric_limits<double>::infinity(), "R1", 0.5 ); chartBuilder.addBarEntry( "T1_The_red_Fox", "W1", "", std::numeric_limits<double>::infinity(), "R1", "", 0.5 );
chartBuilder.addBarEntry( "T1_The_red_Fox", "W1", "", std::numeric_limits<double>::infinity(), "R2", 0.55 ); chartBuilder.addBarEntry( "T1_The_red_Fox", "W1", "", std::numeric_limits<double>::infinity(), "R2", "", 0.55 );
chartBuilder.addBarEntry( "T1_The_red_Fox", "W3", "", std::numeric_limits<double>::infinity(), "R1", 0.7 ); chartBuilder.addBarEntry( "T1_The_red_Fox", "W3", "", std::numeric_limits<double>::infinity(), "R1", "", 0.7 );
chartBuilder.addBarEntry( "T1_The_red_Fox", "W3", "", std::numeric_limits<double>::infinity(), "R2", 0.75 ); chartBuilder.addBarEntry( "T1_The_red_Fox", "W3", "", std::numeric_limits<double>::infinity(), "R2", "", 0.75 );
chartBuilder.addBarEntry( "T1_The_red_Fox", "W2", "", std::numeric_limits<double>::infinity(), "R1", 1.05 ); chartBuilder.addBarEntry( "T1_The_red_Fox", "W2", "", std::numeric_limits<double>::infinity(), "R1", "", 1.05 );
chartBuilder.addBarEntry( "T1_The_red_Fox", "W2", "", std::numeric_limits<double>::infinity(), "R2", 1.0 ); chartBuilder.addBarEntry( "T1_The_red_Fox", "W2", "", std::numeric_limits<double>::infinity(), "R2", "", 1.0 );
chartBuilder.addBarEntry( "T2", "W1", "", std::numeric_limits<double>::infinity(), "R1", 1.5 ); chartBuilder.addBarEntry( "T2", "W1", "", std::numeric_limits<double>::infinity(), "R1", "", 1.5 );
chartBuilder.addBarEntry( "T2", "W1", "", std::numeric_limits<double>::infinity(), "R2", 1.5 ); chartBuilder.addBarEntry( "T2", "W1", "", std::numeric_limits<double>::infinity(), "R2", "", 1.5 );
chartBuilder.addBarEntry( "T2", "W2", "", std::numeric_limits<double>::infinity(), "R1", 2.0 ); chartBuilder.addBarEntry( "T2", "W2", "", std::numeric_limits<double>::infinity(), "R1", "", 2.0 );
chartBuilder.addBarEntry( "T2", "W2", "", std::numeric_limits<double>::infinity(), "R2", 2.0 ); chartBuilder.addBarEntry( "T2", "W2", "", std::numeric_limits<double>::infinity(), "R2", "", 2.0 );
chartBuilder.addBarEntry( "T3", "W1", "1", std::numeric_limits<double>::infinity(), "R1", 1.5 ); chartBuilder.addBarEntry( "T3", "W1", "1", std::numeric_limits<double>::infinity(), "R1", "", 1.5 );
chartBuilder.addBarEntry( "T3", "W1", "2", std::numeric_limits<double>::infinity(), "R2", 1.5 ); chartBuilder.addBarEntry( "T3", "W1", "2", std::numeric_limits<double>::infinity(), "R2", "", 1.5 );
chartBuilder.addBarEntry( "T3", "W2", "3", std::numeric_limits<double>::infinity(), "R1", 2.0 ); chartBuilder.addBarEntry( "T3", "W2", "3", std::numeric_limits<double>::infinity(), "R1", "", 2.0 );
chartBuilder.addBarEntry( "T3", "W2", "4", std::numeric_limits<double>::infinity(), "R1", 2.0 ); chartBuilder.addBarEntry( "T3", "W2", "4", std::numeric_limits<double>::infinity(), "R1", "", 2.0 );
chartBuilder.addBarEntry( "T3", "W2", "5", std::numeric_limits<double>::infinity(), "R1", 2.0 ); chartBuilder.addBarEntry( "T3", "W2", "5", std::numeric_limits<double>::infinity(), "R1", "", 2.0 );
chartBuilder.addBarEntry( "T4", "W1", "1", std::numeric_limits<double>::infinity(), "R1", 1.5 ); chartBuilder.addBarEntry( "T4", "W1", "1", std::numeric_limits<double>::infinity(), "R1", "", 1.5 );
chartBuilder.addBarEntry( "T4", "W1", "2", std::numeric_limits<double>::infinity(), "R2", 1.5 ); chartBuilder.addBarEntry( "T4", "W1", "2", std::numeric_limits<double>::infinity(), "R2", "", 1.5 );
chartBuilder.addBarEntry( "T4", "W2", "3", std::numeric_limits<double>::infinity(), "R1", 2.0 ); chartBuilder.addBarEntry( "T4", "W2", "3", std::numeric_limits<double>::infinity(), "R1", "", 2.0 );
chartBuilder.addBarEntry( "T4", "W2", "4", std::numeric_limits<double>::infinity(), "R2", 2.0 ); chartBuilder.addBarEntry( "T4", "W2", "4", std::numeric_limits<double>::infinity(), "R2", "", 2.0 );
chartBuilder.addBarEntry( "T4", "W1", "1", std::numeric_limits<double>::infinity(), "R1", 1.6 ); chartBuilder.addBarEntry( "T4", "W1", "1", std::numeric_limits<double>::infinity(), "R1", "", 1.6 );
chartBuilder.addBarEntry( "T4", "W1", "2", std::numeric_limits<double>::infinity(), "R2", 1.6 ); chartBuilder.addBarEntry( "T4", "W1", "2", std::numeric_limits<double>::infinity(), "R2", "", 1.6 );
chartBuilder.addBarEntry( "T4", "W2", "3", std::numeric_limits<double>::infinity(), "R1", 2.6 ); chartBuilder.addBarEntry( "T4", "W2", "3", std::numeric_limits<double>::infinity(), "R1", "", 2.6 );
chartBuilder.addBarEntry( "T4", "W2", "4", std::numeric_limits<double>::infinity(), "R2", -0.3 ); chartBuilder.addBarEntry( "T4", "W2", "4", std::numeric_limits<double>::infinity(), "R2", "", -0.3 );
chartBuilder.addBarEntry( "T5", "", "G1", 1.5, "R3", 1.5 ); chartBuilder.addBarEntry( "T5", "", "", 1.5, "R3", "G1", 1.5 );
chartBuilder.addBarEntry( "T5", "", "G2", 1.5, "R3", 1.5 ); chartBuilder.addBarEntry( "T5", "", "", 1.5, "R3", "G2", 1.5 );
chartBuilder.addBarEntry( "T5", "", "G3", 2.0, "R3", 2.0 ); chartBuilder.addBarEntry( "T5", "", "", 2.0, "R3", "G3", 2.0 );
chartBuilder.addBarEntry( "T5", "", "G4", 2.0, "R3", 2.0 ); chartBuilder.addBarEntry( "T5", "", "", 2.0, "R3", "G4", 2.0 );
chartBuilder.addBarEntry( "T5", "", "G5", 1.6, "R3", 1.6 ); chartBuilder.addBarEntry( "T5", "", "", 1.6, "R3", "G5", 1.6 );
chartBuilder.addBarEntry( "T5", "", "G6", 1.6, "R3", 1.6 ); chartBuilder.addBarEntry( "T5", "", "", 1.6, "R3", "G6", 1.6 );
chartBuilder.addBarEntry( "T5", "", "G7", 2.6, "R3", 2.6 ); chartBuilder.addBarEntry( "T5", "", "", 2.6, "R3", "G7", 2.6 );
chartBuilder.addBarEntry( "T5", "", "G8", -0.3, "R3", -0.3 ); chartBuilder.addBarEntry( "T5", "", "", -0.1, "R3", "G8", -0.1 );
chartBuilder.addBarEntry( "", "", "", 1.2, "", 1.2 ); chartBuilder.addBarEntry( "", "", "", 1.2, "", "A", 1.2 );
chartBuilder.addBarEntry( "", "", "", 1.5, "", 1.5 ); chartBuilder.addBarEntry( "", "", "", 1.5, "", "B", 1.5 );
chartBuilder.addBarEntry( "", "", "", 2.3, "", 2.3 ); chartBuilder.addBarEntry( "", "", "", 2.3, "", "C", 2.3 );
chartBuilder.addBarEntry( "", "", "", 2.0, "", 2.0 ); chartBuilder.addBarEntry( "", "", "", 2.0, "", "D", 2.0 );
chartBuilder.addBarEntry( "", "", "", 1.6, "", 1.6 ); chartBuilder.addBarEntry( "", "", "", 1.6, "", "E", 1.6 );
chartBuilder.addBarEntry( "", "", "", 2.4, "", -2.4 ); chartBuilder.addBarEntry( "", "", "", 2.4, "", "F", -2.4 );
chartBuilder.addBarChartToPlot( m_plotWidget ); chartBuilder.addBarChartToPlot( m_plotWidget );

View File

@@ -25,7 +25,9 @@
#include "qwt_painter.h" #include "qwt_painter.h"
#include "qwt_plot.h" #include "qwt_plot.h"
#include "qwt_plot_barchart.h" #include "qwt_plot_barchart.h"
#include "qwt_plot_scaleitem.h"
#include "qwt_scale_draw.h" #include "qwt_scale_draw.h"
#include "qwt_scale_widget.h"
#include <limits> #include <limits>
#include <map> #include <map>
@@ -196,9 +198,11 @@ void RiuGroupedBarChartBuilder::addBarEntry( const QString& majorTickText,
const QString& minTickText, const QString& minTickText,
const double sortValue, const double sortValue,
const QString& legendText, const QString& legendText,
const QString& barText,
const double value ) const double value )
{ {
m_sortedBarEntries.insert( BarEntry( majorTickText, midTickText, minTickText, sortValue, legendText, value ) ); m_sortedBarEntries.insert(
BarEntry( majorTickText, midTickText, minTickText, sortValue, legendText, barText, value ) );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -225,11 +229,12 @@ void RiuGroupedBarChartBuilder::addBarChartToPlot( QwtPlot* plot )
std::map<QString, QVector<QPointF>> legendToBarPointsMap; std::map<QString, QVector<QPointF>> legendToBarPointsMap;
std::map<double, std::pair<QwtScaleDiv::TickType, QString>> positionedAxisTexts; std::map<double, std::pair<QwtScaleDiv::TickType, QString>> groupPositionedAxisTexts;
std::map<double, std::pair<QwtScaleDiv::TickType, QString>> positionedBarLabels;
QList<double> majTickPoss; QList<double> majTickPositions;
QList<double> midTickPoss; QList<double> midTickPositions;
QList<double> minTickPoss; QList<double> minTickPositions;
// clang-format off // clang-format off
auto addGroupTickText = [&]( double groupStartPos, QString tickText, QList<double>& groupTickPosList ) auto addGroupTickText = [&]( double groupStartPos, QString tickText, QList<double>& groupTickPosList )
@@ -238,8 +243,8 @@ void RiuGroupedBarChartBuilder::addBarChartToPlot( QwtPlot* plot )
double tickPos = midPoint( groupStartPos, currentBarPosition ); double tickPos = midPoint( groupStartPos, currentBarPosition );
QwtScaleDiv::TickType ttyp = (&groupTickPosList == &majTickPoss ) ? QwtScaleDiv::MajorTick QwtScaleDiv::TickType ttyp = (&groupTickPosList == &majTickPositions ) ? QwtScaleDiv::MajorTick
: ( &groupTickPosList == &midTickPoss ) ? QwtScaleDiv::MediumTick : ( &groupTickPosList == &midTickPositions ) ? QwtScaleDiv::MediumTick
: QwtScaleDiv::MinorTick; : QwtScaleDiv::MinorTick;
// Make sure we do not get ticks of different level exactly at the same spot, // Make sure we do not get ticks of different level exactly at the same spot,
@@ -248,12 +253,14 @@ void RiuGroupedBarChartBuilder::addBarChartToPlot( QwtPlot* plot )
if( ttyp == QwtScaleDiv::MinorTick ) tickPos += 2e-4; if( ttyp == QwtScaleDiv::MinorTick ) tickPos += 2e-4;
if( ttyp == QwtScaleDiv::MediumTick ) tickPos += 1e-4; if( ttyp == QwtScaleDiv::MediumTick ) tickPos += 1e-4;
positionedAxisTexts[tickPos] = { ttyp, tickText }; groupPositionedAxisTexts[tickPos] = { ttyp, tickText };
groupTickPosList.push_back( tickPos ); groupTickPosList.push_back( tickPos );
}; };
// clang-format on // clang-format on
// Loop over entries, calculate tick positions and bar positions as we go
for ( const BarEntry& barDef : m_sortedBarEntries ) for ( const BarEntry& barDef : m_sortedBarEntries )
{ {
bool hasAnyMajTics = !majTickTexts.empty(); bool hasAnyMajTics = !majTickTexts.empty();
@@ -263,9 +270,9 @@ void RiuGroupedBarChartBuilder::addBarChartToPlot( QwtPlot* plot )
if ( isFinishingMajGroup ) if ( isFinishingMajGroup )
{ {
addGroupTickText( currentMajGroupStartPos, previousMajText, majTickPoss ); addGroupTickText( currentMajGroupStartPos, previousMajText, majTickPositions );
addGroupTickText( currentMidGroupStartPos, previousMidText, midTickPoss ); addGroupTickText( currentMidGroupStartPos, previousMidText, midTickPositions );
addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPoss ); addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPositions );
currentBarPosition += majGroupSpacing; currentBarPosition += majGroupSpacing;
} }
@@ -291,8 +298,8 @@ void RiuGroupedBarChartBuilder::addBarChartToPlot( QwtPlot* plot )
if ( isFinishingMidGroup ) if ( isFinishingMidGroup )
{ {
addGroupTickText( currentMidGroupStartPos, previousMidText, midTickPoss ); addGroupTickText( currentMidGroupStartPos, previousMidText, midTickPositions );
addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPoss ); addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPositions );
currentBarPosition += midGroupSpacing; currentBarPosition += midGroupSpacing;
} }
@@ -315,7 +322,7 @@ void RiuGroupedBarChartBuilder::addBarChartToPlot( QwtPlot* plot )
if ( isFinishingMinGroup ) if ( isFinishingMinGroup )
{ {
addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPoss ); addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPositions );
currentBarPosition += minGroupSpacing; currentBarPosition += minGroupSpacing;
} }
@@ -342,27 +349,34 @@ void RiuGroupedBarChartBuilder::addBarChartToPlot( QwtPlot* plot )
} }
barPoints->push_back( {currentBarPosition, barDef.m_value} ); barPoints->push_back( {currentBarPosition, barDef.m_value} );
if ( !barDef.m_barText.isEmpty() )
{
positionedBarLabels[currentBarPosition] = {QwtScaleDiv::MinorTick, barDef.m_barText};
}
// Increment the bar position for the next bar // Increment the bar position for the next bar
currentBarPosition += 1.0; currentBarPosition += 1.0;
} }
// Add group tick texts for the last groups // Add group tick texts for the last groups
{
if ( !previousMajText.isEmpty() ) if ( !previousMajText.isEmpty() )
{ {
addGroupTickText( currentMajGroupStartPos, previousMajText, majTickPoss ); addGroupTickText( currentMajGroupStartPos, previousMajText, majTickPositions );
} }
if ( !previousMidText.isEmpty() ) if ( !previousMidText.isEmpty() )
{ {
addGroupTickText( currentMidGroupStartPos, previousMidText, midTickPoss ); addGroupTickText( currentMidGroupStartPos, previousMidText, midTickPositions );
} }
if ( !previousMinText.isEmpty() ) if ( !previousMinText.isEmpty() )
{ {
addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPoss ); addGroupTickText( currentMinGroupStartPos, previousMinText, minTickPositions );
} }
}
// Create QwtBarCharts for each of the legend groups
int idx = 0; int idx = 0;
for ( const auto& legendToBarPointsPair : legendToBarPointsMap ) for ( const auto& legendToBarPointsPair : legendToBarPointsMap )
@@ -374,28 +388,65 @@ void RiuGroupedBarChartBuilder::addBarChartToPlot( QwtPlot* plot )
idx++; idx++;
} }
// Set up the axis to contain group texts and tick marks
{
QwtPlot::Axis axis = QwtPlot::xBottom; QwtPlot::Axis axis = QwtPlot::xBottom;
RiuBarChartScaleDraw* scaleDrawer = new RiuBarChartScaleDraw( positionedAxisTexts );
if ( m_orientation == Qt::Horizontal ) if ( m_orientation == Qt::Horizontal )
{ {
axis = QwtPlot::yLeft; axis = QwtPlot::yLeft;
} }
plot->setAxisScaleDraw( axis, scaleDrawer ); QwtScaleDiv groupAxisScaleDiv( 0, currentBarPosition );
{
QwtScaleDiv scaleDiv( 0, currentBarPosition ); if ( majTickPositions.size() ) groupAxisScaleDiv.setTicks( QwtScaleDiv::MajorTick, majTickPositions );
if ( midTickPositions.size() ) groupAxisScaleDiv.setTicks( QwtScaleDiv::MediumTick, midTickPositions );
if ( majTickPoss.size() ) scaleDiv.setTicks( QwtScaleDiv::MajorTick, majTickPoss ); if ( minTickPositions.size() ) groupAxisScaleDiv.setTicks( QwtScaleDiv::MinorTick, minTickPositions );
if ( midTickPoss.size() ) scaleDiv.setTicks( QwtScaleDiv::MediumTick, midTickPoss );
if ( minTickPoss.size() ) scaleDiv.setTicks( QwtScaleDiv::MinorTick, minTickPoss );
if ( m_orientation == Qt::Horizontal ) if ( m_orientation == Qt::Horizontal )
{ {
scaleDiv.invert(); groupAxisScaleDiv.invert();
}
} }
plot->setAxisScaleDiv( axis, scaleDiv ); RiuBarChartScaleDraw* scaleDrawer = new RiuBarChartScaleDraw( groupPositionedAxisTexts );
plot->setAxisScaleDraw( axis, scaleDrawer );
plot->setAxisScaleDiv( axis, groupAxisScaleDiv );
}
// Add texts on the bars inside the plot
{
QwtScaleDraw::Alignment alignment = QwtScaleDraw::TopScale;
if ( m_orientation == Qt::Horizontal )
{
alignment = QwtScaleDraw::RightScale;
}
QwtScaleDiv barTextScaleDiv( 0, currentBarPosition );
{
QList<double> onBarTickPositions;
for ( const auto& doubleStuffPair : positionedBarLabels )
{
onBarTickPositions.push_back( doubleStuffPair.first );
}
barTextScaleDiv.setTicks( QwtScaleDiv::MinorTick, onBarTickPositions );
if ( m_orientation == Qt::Horizontal )
{
barTextScaleDiv.invert();
}
}
RiuBarChartScaleDraw* barTextScaleDrawer = new RiuBarChartScaleDraw( positionedBarLabels );
barTextScaleDrawer->setAlignment( alignment );
QwtPlotScaleItem* barTextScale = new QwtPlotScaleItem( alignment, 0.0 );
barTextScale->setScaleDraw( barTextScaleDrawer );
barTextScale->setScaleDiv( barTextScaleDiv );
barTextScale->attach( plot );
barTextScale->setZ( 1000 );
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -437,17 +488,19 @@ RiuGroupedBarChartBuilder::BarEntry::BarEntry()
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RiuGroupedBarChartBuilder::BarEntry::BarEntry( QString majorTickText, RiuGroupedBarChartBuilder::BarEntry::BarEntry( const QString& majorTickText,
QString midTickText, const QString& midTickText,
QString minTickText, const QString& minTickText,
double sortValue, const double sortValue,
QString legendText, const QString& legendText,
double value ) const QString& barText,
const double value )
: m_majTickText( majorTickText ) : m_majTickText( majorTickText )
, m_midTickText( midTickText ) , m_midTickText( midTickText )
, m_minTickText( minTickText ) , m_minTickText( minTickText )
, m_sortValue( sortValue ) , m_sortValue( sortValue )
, m_legendText( legendText ) , m_legendText( legendText )
, m_barText( barText )
, m_value( value ) , m_value( value )
{ {
} }

View File

@@ -39,6 +39,7 @@ public:
const QString& minTickText, const QString& minTickText,
const double sortValue, const double sortValue,
const QString& legendText, const QString& legendText,
const QString& barText,
const double value ); const double value );
void addBarChartToPlot( QwtPlot* plot ); void addBarChartToPlot( QwtPlot* plot );
@@ -58,18 +59,20 @@ private:
{ {
BarEntry(); BarEntry();
BarEntry( QString majorTickText, BarEntry( const QString& majorTickText,
QString midTickText, const QString& midTickText,
QString minTickText, const QString& minTickText,
double sortValue, const double sortValue,
QString legendText, const QString& legendText,
double value ); const QString& barText,
const double value );
QString m_majTickText; QString m_majTickText;
QString m_midTickText; QString m_midTickText;
QString m_minTickText; QString m_minTickText;
double m_sortValue; double m_sortValue;
QString m_legendText; QString m_legendText;
QString m_barText;
double m_value; double m_value;