Support more than one data point in a diagram
This commit is contained in:
parent
d4bc4e12f5
commit
ad03c0f6a0
|
@ -9,17 +9,21 @@ class Diagram::PrivateData
|
|||
{
|
||||
}
|
||||
|
||||
QVector<QPointF> dataPoints;
|
||||
QVector<QVector<QPointF> > dataPoints;
|
||||
int xGridLines = -1;
|
||||
qreal yMax = -1;
|
||||
Qsk::Position position = Qsk::Bottom;
|
||||
Types types = Area;
|
||||
QVector<Types> types;
|
||||
};
|
||||
|
||||
QSK_SUBCONTROL( Diagram, Chart )
|
||||
QSK_SUBCONTROL( Diagram, Segments )
|
||||
QSK_SUBCONTROL( Diagram, ChartLine )
|
||||
QSK_SUBCONTROL( Diagram, ChartArea )
|
||||
QSK_SUBCONTROL( Diagram, ChartLine1 )
|
||||
QSK_SUBCONTROL( Diagram, ChartArea1 )
|
||||
QSK_SUBCONTROL( Diagram, ChartLine2 )
|
||||
QSK_SUBCONTROL( Diagram, ChartArea2 )
|
||||
QSK_SUBCONTROL( Diagram, ChartLine3 )
|
||||
QSK_SUBCONTROL( Diagram, ChartArea3 )
|
||||
|
||||
Diagram::Diagram( QQuickItem* parent )
|
||||
: Inherited( parent )
|
||||
|
@ -31,24 +35,20 @@ Diagram::~Diagram()
|
|||
{
|
||||
}
|
||||
|
||||
QVector<QPointF> Diagram::dataPoints() const
|
||||
QVector< QVector<QPointF> > Diagram::dataPoints() const
|
||||
{
|
||||
return m_data->dataPoints;
|
||||
}
|
||||
|
||||
void Diagram::setDataPoints( const QVector<QPointF>& dataPoints )
|
||||
void Diagram::addDataPoints( const QVector<QPointF>& dataPoints, const Types& types )
|
||||
{
|
||||
m_data->dataPoints = dataPoints;
|
||||
m_data->dataPoints.append( dataPoints );
|
||||
m_data->types.append( types );
|
||||
}
|
||||
|
||||
Diagram::Types Diagram::types() const
|
||||
Diagram::Types Diagram::typesAt( uint pos ) const
|
||||
{
|
||||
return m_data->types;
|
||||
}
|
||||
|
||||
void Diagram::setTypes( Types types )
|
||||
{
|
||||
m_data->types = types;
|
||||
return m_data->types.at( pos );
|
||||
}
|
||||
|
||||
qreal Diagram::yMax() const
|
||||
|
|
|
@ -12,7 +12,7 @@ class Diagram : public QskControl
|
|||
using Inherited = QskControl;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Chart, Segments, ChartLine, ChartArea )
|
||||
QSK_SUBCONTROLS( Chart, Segments, ChartLine1, ChartArea1, ChartLine2, ChartArea2, ChartLine3, ChartArea3 )
|
||||
|
||||
enum Type
|
||||
{
|
||||
|
@ -25,11 +25,10 @@ class Diagram : public QskControl
|
|||
Diagram( QQuickItem* parent = nullptr );
|
||||
~Diagram() override;
|
||||
|
||||
QVector<QPointF> dataPoints() const;
|
||||
void setDataPoints( const QVector<QPointF>& dataPoints );
|
||||
QVector< QVector<QPointF> > dataPoints() const;
|
||||
void addDataPoints( const QVector<QPointF>& dataPoints, const Types& types );
|
||||
|
||||
Types types() const;
|
||||
void setTypes( Types types );
|
||||
Types typesAt( uint pos ) const;
|
||||
|
||||
qreal yMax() const;
|
||||
void setYMax( qreal yMax );
|
||||
|
|
|
@ -3,6 +3,39 @@
|
|||
#include "nodes/DiagramDataNode.h"
|
||||
#include "nodes/DiagramSegmentsNode.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
QskAspect::Subcontrol areaForIndex( int i )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
case 1:
|
||||
return Diagram::ChartArea2;
|
||||
|
||||
case 2:
|
||||
return Diagram::ChartArea3;
|
||||
|
||||
default:
|
||||
return Diagram::ChartArea1;
|
||||
}
|
||||
}
|
||||
|
||||
QskAspect::Subcontrol lineForIndex( int i )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
case 1:
|
||||
return Diagram::ChartLine2;
|
||||
|
||||
case 2:
|
||||
return Diagram::ChartLine3;
|
||||
|
||||
default:
|
||||
return Diagram::ChartLine1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DiagramSkinlet::DiagramSkinlet( QskSkin* skin )
|
||||
: QskSkinlet( skin )
|
||||
{
|
||||
|
@ -46,59 +79,78 @@ QSGNode* DiagramSkinlet::updateSubNode(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
QSGNode* DiagramSkinlet::updateChartNode( const Diagram* distribution, QSGNode* node ) const
|
||||
QSGNode* DiagramSkinlet::updateChartNode( const Diagram* diagram, QSGNode* node ) const
|
||||
{
|
||||
if( node == nullptr )
|
||||
{
|
||||
node = new IdlChartNode;
|
||||
node = new IdlChartNode; // ### rename
|
||||
}
|
||||
|
||||
using Q = Diagram;
|
||||
const QRectF rect = distribution->subControlRect( Q::Chart );
|
||||
const QVector<QPointF> dataPoints = distribution->dataPoints();
|
||||
const qreal yMax = distribution->yMax();
|
||||
const Qsk::Position position = distribution->chartPosition();
|
||||
int lineWidth = distribution->metric( Diagram::ChartLine | QskAspect::Size );
|
||||
const QRectF rect = diagram->subControlRect( Q::Chart );
|
||||
const qreal yMax = diagram->yMax();
|
||||
const Qsk::Position position = diagram->chartPosition();
|
||||
QVector<Diagram::Type> types = {Diagram::Line, Diagram::Area};
|
||||
|
||||
int nodeIndex = 0;
|
||||
|
||||
for( int i = 0; i < types.size(); ++i )
|
||||
for( int i = 0; i < diagram->dataPoints().size(); ++i )
|
||||
{
|
||||
if( distribution->types() & types.at( i ) )
|
||||
QSGNode* chartNode;
|
||||
|
||||
if( node->childCount() > i )
|
||||
{
|
||||
IdlChartNode* lineNode;
|
||||
chartNode = node->childAtIndex( i );
|
||||
}
|
||||
else
|
||||
{
|
||||
chartNode = new QSGNode;
|
||||
node->appendChildNode( chartNode );
|
||||
}
|
||||
|
||||
if( node->childCount() > nodeIndex )
|
||||
const QVector<QPointF> dataPoints = diagram->dataPoints().at( i );
|
||||
int nodeIndex = 0;
|
||||
QskAspect::Subcontrol lineSubcontrol = lineForIndex( i );
|
||||
QskAspect::Subcontrol areaSubcontrol = areaForIndex( i );
|
||||
int lineWidth = diagram->metric( lineSubcontrol | QskAspect::Size );
|
||||
|
||||
for( int j = 0; j < types.size(); ++j )
|
||||
{
|
||||
if( diagram->typesAt( i ) & types.at( j ) )
|
||||
{
|
||||
lineNode = static_cast<IdlChartNode*>( node->childAtIndex( nodeIndex ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
lineNode = new IdlChartNode;
|
||||
node->appendChildNode( lineNode );
|
||||
}
|
||||
IdlChartNode* dataPointNode;
|
||||
|
||||
const IdlChartNode::Type nodeType = ( types.at( i ) == Diagram::Line ) ? IdlChartNode::Line : IdlChartNode::Area;
|
||||
const QColor color = ( types.at( i ) == Diagram::Line ) ? distribution->color( Q::ChartLine )
|
||||
: distribution->color( Q::ChartArea );
|
||||
if( chartNode->childCount() > nodeIndex )
|
||||
{
|
||||
dataPointNode = static_cast<IdlChartNode*>( chartNode->childAtIndex( nodeIndex ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
dataPointNode = new IdlChartNode;
|
||||
chartNode->appendChildNode( dataPointNode );
|
||||
}
|
||||
|
||||
lineNode->update( rect, nodeType, color, dataPoints, yMax, position, lineWidth );
|
||||
nodeIndex++;
|
||||
const IdlChartNode::Type nodeType = ( types.at( j ) == Diagram::Line ) ? IdlChartNode::Line : IdlChartNode::Area;
|
||||
const QColor color = ( types.at( j ) == Diagram::Line ) ? diagram->color( lineSubcontrol )
|
||||
: diagram->color( areaSubcontrol );
|
||||
|
||||
dataPointNode->update( rect, nodeType, color, dataPoints, yMax, position, lineWidth );
|
||||
nodeIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
while( nodeIndex < chartNode->childCount() )
|
||||
{
|
||||
chartNode->removeChildNode( chartNode->childAtIndex( nodeIndex++ ) );
|
||||
}
|
||||
}
|
||||
|
||||
while( nodeIndex < node->childCount() )
|
||||
{
|
||||
node->removeChildNode( node->childAtIndex( nodeIndex++ ) );
|
||||
}
|
||||
// ### also check for superfluous nodes here
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
QSGNode* DiagramSkinlet::updateSeparatorNode( const Diagram* discharge, QSGNode* node ) const
|
||||
QSGNode* DiagramSkinlet::updateSeparatorNode( const Diagram* diagram, QSGNode* node ) const
|
||||
{
|
||||
const int xGridLines = discharge->xGridLines();
|
||||
const int xGridLines = diagram->xGridLines();
|
||||
|
||||
if( xGridLines <= 0 )
|
||||
{
|
||||
|
@ -113,9 +165,9 @@ QSGNode* DiagramSkinlet::updateSeparatorNode( const Diagram* discharge, QSGNode*
|
|||
}
|
||||
|
||||
using Q = Diagram;
|
||||
const QRectF rect = discharge->subControlRect( Q::Chart );
|
||||
const QColor color = discharge->color( Q::Segments );
|
||||
const QVector<QPointF> dataPoints = discharge->dataPoints();
|
||||
const QRectF rect = diagram->subControlRect( Q::Chart );
|
||||
const QColor color = diagram->color( Q::Segments );
|
||||
const QVector< QVector<QPointF> > dataPoints = diagram->dataPoints();
|
||||
|
||||
separatorNode->update( rect, color, dataPoints, xGridLines );
|
||||
|
||||
|
|
|
@ -156,8 +156,9 @@ void Skin::initHints( const Palette& palette )
|
|||
|
||||
|
||||
// new diagram:
|
||||
ed.setMetric( Diagram::ChartLine | QskAspect::Size, 2 );
|
||||
ed.setColor( Diagram::ChartArea, "#886776ff" );
|
||||
ed.setColor( Diagram::ChartArea1, "#886776ff" );
|
||||
ed.setColor( Diagram::ChartArea2, "#88ff3122" );
|
||||
ed.setColor( Diagram::ChartArea3, "#88ff7d34" );
|
||||
|
||||
|
||||
// light intensity:
|
||||
|
@ -178,7 +179,6 @@ void Skin::initHints( const Palette& palette )
|
|||
ed.setGradient( RoundButton::Panel, palette.roundButton );
|
||||
ed.setBoxBorderColors( WeekdayBox::Panel, palette.weekdayBox );
|
||||
ed.setColor( QskTextLabel::Text, palette.text );
|
||||
ed.setColor( Diagram::ChartLine, Qt::transparent );
|
||||
ed.setColor( WeekdayLabel::Text, palette.text );
|
||||
ed.setColor( ShadowPositioner::Panel, palette.shadow );
|
||||
}
|
||||
|
|
|
@ -70,23 +70,33 @@ UsageDiagram::UsageDiagram( QQuickItem* parent )
|
|||
setAutoAddChildren( false );
|
||||
setAutoLayoutChildren( true );
|
||||
|
||||
m_diagram->setTypes( Diagram::Line | Diagram::Area );
|
||||
m_diagram->setChartPosition( Qsk::Bottom );
|
||||
int number = 100;
|
||||
QVector<QPointF> dataPoints1;
|
||||
dataPoints1.reserve( number );
|
||||
std::vector<qreal> yValues1 = {40, 20, 30, 50, 30, 70, 80, 100, 90, 60};
|
||||
qreal t0 = yValues1[0];
|
||||
qreal step = 10;
|
||||
boost::math::cubic_b_spline<qreal> spline1( yValues1.data(), yValues1.size(), t0, step );
|
||||
|
||||
for( int x = 0; x < number; ++x )
|
||||
std::vector< std::vector<qreal> > yValues =
|
||||
{
|
||||
qreal y = spline1( x );
|
||||
dataPoints1.append( QPointF( x, y ) );
|
||||
{40, 20, 30, 50, 30, 70, 80, 100, 90, 60},
|
||||
{15, 70, 40, 60, 10, 90, 20, 40, 45, 50},
|
||||
{70, 40, 60, 10, 70, 20, 50, 20, 30, 40}
|
||||
};
|
||||
|
||||
for( int i = 0; i < 3; ++i )
|
||||
{
|
||||
auto y = yValues.at( i );
|
||||
|
||||
QVector<QPointF> dataPoints;
|
||||
dataPoints.reserve( number );
|
||||
qreal t0 = y[0];
|
||||
qreal step = 10;
|
||||
boost::math::cubic_b_spline<qreal> spline( y.data(), y.size(), t0, step );
|
||||
|
||||
for( int x = 0; x < number; ++x )
|
||||
{
|
||||
const qreal y = spline( x );
|
||||
dataPoints.append( QPointF( x, y ) );
|
||||
}
|
||||
|
||||
m_diagram->addDataPoints( dataPoints, Diagram::Area );
|
||||
}
|
||||
|
||||
m_diagram->setDataPoints( dataPoints1 );
|
||||
m_diagram->setYMax( 100 );
|
||||
addItem( m_diagram );
|
||||
|
||||
|
@ -113,4 +123,11 @@ UsageDiagram::UsageDiagram( QQuickItem* parent )
|
|||
m_captionBox->addItem( new CaptionItem( CaptionItem::Gas, this ) );
|
||||
}
|
||||
|
||||
void UsageDiagram::updateLayout()
|
||||
{
|
||||
auto weekdaysHeight = m_weekdays->preferredSize().height();
|
||||
m_diagram->setHeight( m_diagram->height() - weekdaysHeight );
|
||||
m_captionBox->setPosition( {0, 0} );
|
||||
}
|
||||
|
||||
#include "Diagram.moc"
|
||||
|
|
|
@ -130,6 +130,8 @@ class UsageDiagram : public Box
|
|||
|
||||
UsageDiagram( QQuickItem* parent );
|
||||
|
||||
void updateLayout() override;
|
||||
|
||||
QskAspect::Subcontrol effectiveSubcontrol(
|
||||
QskAspect::Subcontrol subControl ) const override final
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@ IdlChartSegmentsNode::IdlChartSegmentsNode()
|
|||
setMaterial( &m_material );
|
||||
}
|
||||
|
||||
void IdlChartSegmentsNode::update( const QRectF& rect, const QColor& color, const QVector<QPointF>& dataPoints, int xGridLines )
|
||||
void IdlChartSegmentsNode::update( const QRectF& rect, const QColor& color, const QVector<QVector<QPointF> >& dataPoints, int xGridLines )
|
||||
{
|
||||
Q_UNUSED( rect );
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ class IdlChartSegmentsNode : public QSGGeometryNode
|
|||
public:
|
||||
IdlChartSegmentsNode();
|
||||
|
||||
void update( const QRectF& rect, const QColor& color, const QVector<QPointF>& dataPoints, int xGridLines );
|
||||
void update( const QRectF& rect, const QColor& color, const QVector< QVector<QPointF> >& dataPoints, int xGridLines );
|
||||
|
||||
private:
|
||||
QSGFlatColorMaterial m_material;
|
||||
|
@ -17,6 +17,6 @@ class IdlChartSegmentsNode : public QSGGeometryNode
|
|||
|
||||
QRectF m_rect;
|
||||
QColor m_color;
|
||||
QVector<QPointF> m_dataPoints;
|
||||
QVector< QVector<QPointF> > m_dataPoints;
|
||||
int m_xGridLines;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue