use new Diagram class
This commit is contained in:
parent
0df95fcb37
commit
d4bc4e12f5
|
@ -1,3 +1,5 @@
|
||||||
|
// ### copyright Uwe
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QskControl.h>
|
#include <QskControl.h>
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include "Box.h"
|
#include "Box.h"
|
||||||
#include "BoxWithButtons.h"
|
#include "BoxWithButtons.h"
|
||||||
|
#include "Diagram.h"
|
||||||
|
#include "DiagramSkinlet.h"
|
||||||
#include "LightIntensity.h"
|
#include "LightIntensity.h"
|
||||||
#include "MainContent.h"
|
#include "MainContent.h"
|
||||||
#include "MenuBar.h"
|
#include "MenuBar.h"
|
||||||
|
@ -38,6 +40,8 @@ namespace
|
||||||
|
|
||||||
Skin::Skin( const Palette& palette, QObject* parent ) : QskSkin( parent )
|
Skin::Skin( const Palette& palette, QObject* parent ) : QskSkin( parent )
|
||||||
{
|
{
|
||||||
|
declareSkinlet< Diagram, DiagramSkinlet >();
|
||||||
|
|
||||||
initHints( palette );
|
initHints( palette );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,6 +155,11 @@ void Skin::initHints( const Palette& palette )
|
||||||
ed.setPadding( CaptionBox::Panel, {10, 10, 20, 0} );
|
ed.setPadding( CaptionBox::Panel, {10, 10, 20, 0} );
|
||||||
|
|
||||||
|
|
||||||
|
// new diagram:
|
||||||
|
ed.setMetric( Diagram::ChartLine | QskAspect::Size, 2 );
|
||||||
|
ed.setColor( Diagram::ChartArea, "#886776ff" );
|
||||||
|
|
||||||
|
|
||||||
// light intensity:
|
// light intensity:
|
||||||
ed.setGradient( LightDisplay::ColdPart, { Qt::Horizontal, "#a7b0ff", "#6776ff" } );
|
ed.setGradient( LightDisplay::ColdPart, { Qt::Horizontal, "#a7b0ff", "#6776ff" } );
|
||||||
ed.setGradient( LightDisplay::WarmPart, { Qt::Horizontal, "#feeeb7", "#ff3122" } );
|
ed.setGradient( LightDisplay::WarmPart, { Qt::Horizontal, "#feeeb7", "#ff3122" } );
|
||||||
|
@ -169,6 +178,7 @@ void Skin::initHints( const Palette& palette )
|
||||||
ed.setGradient( RoundButton::Panel, palette.roundButton );
|
ed.setGradient( RoundButton::Panel, palette.roundButton );
|
||||||
ed.setBoxBorderColors( WeekdayBox::Panel, palette.weekdayBox );
|
ed.setBoxBorderColors( WeekdayBox::Panel, palette.weekdayBox );
|
||||||
ed.setColor( QskTextLabel::Text, palette.text );
|
ed.setColor( QskTextLabel::Text, palette.text );
|
||||||
|
ed.setColor( Diagram::ChartLine, Qt::transparent );
|
||||||
ed.setColor( WeekdayLabel::Text, palette.text );
|
ed.setColor( WeekdayLabel::Text, palette.text );
|
||||||
ed.setColor( ShadowPositioner::Panel, palette.shadow );
|
ed.setColor( ShadowPositioner::Panel, palette.shadow );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "UsageDiagram.h"
|
#include "UsageDiagram.h"
|
||||||
|
|
||||||
|
#include "Diagram.h"
|
||||||
|
|
||||||
#include <QskBoxBorderColors.h>
|
#include <QskBoxBorderColors.h>
|
||||||
#include <QskBoxBorderMetrics.h>
|
#include <QskBoxBorderMetrics.h>
|
||||||
#include <QskBoxShapeMetrics.h>
|
#include <QskBoxShapeMetrics.h>
|
||||||
|
@ -11,6 +13,7 @@
|
||||||
#include <QPainterPath>
|
#include <QPainterPath>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <boost/math/interpolators/cubic_b_spline.hpp>
|
||||||
|
|
||||||
QSK_SUBCONTROL( WeekdayLabel, Panel )
|
QSK_SUBCONTROL( WeekdayLabel, Panel )
|
||||||
QSK_SUBCONTROL( WeekdayLabel, Text )
|
QSK_SUBCONTROL( WeekdayLabel, Text )
|
||||||
|
@ -56,92 +59,38 @@ CaptionItem::CaptionItem( QskAspect::State state, QQuickItem* parent )
|
||||||
box->setFixedSize( {size, size} );
|
box->setFixedSize( {size, size} );
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
float distance( const QPointF& pt1, const QPointF& pt2 )
|
|
||||||
{
|
|
||||||
float hd = ( pt1.x() - pt2.x() ) * ( pt1.x() - pt2.x() );
|
|
||||||
float vd = ( pt1.y() - pt2.y() ) * ( pt1.y() - pt2.y() );
|
|
||||||
return std::sqrt( hd + vd );
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF getLineStart( const QPointF& pt1, const QPointF& pt2 )
|
|
||||||
{
|
|
||||||
QPointF pt;
|
|
||||||
float rat = 10.0 / distance( pt1, pt2 );
|
|
||||||
|
|
||||||
if( rat > 0.5 )
|
|
||||||
{
|
|
||||||
rat = 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
pt.setX( ( 1.0 - rat ) * pt1.x() + rat * pt2.x() );
|
|
||||||
pt.setY( ( 1.0 - rat ) * pt1.y() + rat * pt2.y() );
|
|
||||||
return pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF getLineEnd( const QPointF& pt1, const QPointF& pt2 )
|
|
||||||
{
|
|
||||||
QPointF pt;
|
|
||||||
float rat = 10.0 / distance( pt1, pt2 );
|
|
||||||
|
|
||||||
if( rat > 0.5 )
|
|
||||||
{
|
|
||||||
rat = 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
pt.setX( rat * pt1.x() + ( 1.0 - rat )*pt2.x() );
|
|
||||||
pt.setY( rat * pt1.y() + ( 1.0 - rat )*pt2.y() );
|
|
||||||
return pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPainterPath smoothOut( const QPainterPath& path )
|
|
||||||
{
|
|
||||||
QList<QPointF> points;
|
|
||||||
QPointF p;
|
|
||||||
|
|
||||||
for( int i = 0; i < path.elementCount() - 1; i++ )
|
|
||||||
{
|
|
||||||
p = QPointF( path.elementAt( i ).x, path.elementAt( i ).y );
|
|
||||||
points.append( p );
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF pt1;
|
|
||||||
QPointF pt2;
|
|
||||||
QPainterPath newPath;
|
|
||||||
|
|
||||||
for( int i = 0; i < points.count() - 1; i++ )
|
|
||||||
{
|
|
||||||
pt1 = getLineStart( points[i], points[i + 1] );
|
|
||||||
|
|
||||||
if( i == 0 )
|
|
||||||
{
|
|
||||||
newPath.moveTo( points[0] );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newPath.quadTo( points[i], pt1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
pt2 = getLineEnd( points[i], points[i + 1] );
|
|
||||||
newPath.lineTo( pt2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return newPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr int segments = 7;
|
static constexpr int segments = 7;
|
||||||
|
|
||||||
UsageDiagram::UsageDiagram( QQuickItem* parent )
|
UsageDiagram::UsageDiagram( QQuickItem* parent )
|
||||||
: Box( "", parent )
|
: Box( "", parent )
|
||||||
|
, m_diagram( new Diagram( this ) )
|
||||||
, m_weekdays( new QskGridBox( this ) )
|
, m_weekdays( new QskGridBox( this ) )
|
||||||
, m_content( new DiagramContent( this ) )
|
|
||||||
{
|
{
|
||||||
setAutoAddChildren( false );
|
setAutoAddChildren( false );
|
||||||
setAutoLayoutChildren( true );
|
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 )
|
||||||
|
{
|
||||||
|
qreal y = spline1( x );
|
||||||
|
dataPoints1.append( QPointF( x, y ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_diagram->setDataPoints( dataPoints1 );
|
||||||
|
m_diagram->setYMax( 100 );
|
||||||
|
addItem( m_diagram );
|
||||||
|
|
||||||
|
|
||||||
m_weekdays->setSpacing( 0 );
|
m_weekdays->setSpacing( 0 );
|
||||||
QStringList weekdays = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
|
QStringList weekdays = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
|
||||||
|
|
||||||
|
@ -162,72 +111,6 @@ UsageDiagram::UsageDiagram( QQuickItem* parent )
|
||||||
m_captionBox->addItem( new CaptionItem( CaptionItem::Water, this ) );
|
m_captionBox->addItem( new CaptionItem( CaptionItem::Water, this ) );
|
||||||
m_captionBox->addItem( new CaptionItem( CaptionItem::Electricity, this ) );
|
m_captionBox->addItem( new CaptionItem( CaptionItem::Electricity, this ) );
|
||||||
m_captionBox->addItem( new CaptionItem( CaptionItem::Gas, this ) );
|
m_captionBox->addItem( new CaptionItem( CaptionItem::Gas, this ) );
|
||||||
|
|
||||||
addItem( m_content );
|
|
||||||
}
|
|
||||||
|
|
||||||
void UsageDiagram::updateLayout()
|
|
||||||
{
|
|
||||||
auto* firstWeekday = static_cast<QskControl*>( m_weekdays->itemAt( 1, 0 ) );
|
|
||||||
qreal w = size().width();
|
|
||||||
qreal h = size().height() - ( m_captionBox->size().height() + firstWeekday->size().height() );
|
|
||||||
|
|
||||||
m_content->setSize( { w, h } );
|
|
||||||
m_content->setPosition( { 0, m_captionBox->size().height() } );
|
|
||||||
m_content->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
DiagramContent::DiagramContent( QQuickItem* parent ) : QQuickPaintedItem( parent )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void DiagramContent::paint( QPainter* painter )
|
|
||||||
{
|
|
||||||
painter->setRenderHint( QPainter::Antialiasing, true );
|
|
||||||
|
|
||||||
QPair<QColor, QColor> colors[] =
|
|
||||||
{
|
|
||||||
{"#996776FF", "#116776FF"},
|
|
||||||
{"#aaFF3122", "#11FF3122"},
|
|
||||||
{"#FF7D34", "#11FF7D34"}
|
|
||||||
};
|
|
||||||
|
|
||||||
qreal yValues[][8] =
|
|
||||||
{
|
|
||||||
{0.8, 0.85, 0.92, 0.5, 0.88, 0.7, 0.8, 0.3},
|
|
||||||
{0.2, 0.6, 0.5, 0.9, 0.3, 0.4, 0.8, 0.4},
|
|
||||||
{0.5, 0.4, 0.7, 0.1, 0.6, 0.9, 0.3, 0.1}
|
|
||||||
};
|
|
||||||
|
|
||||||
for( int i = 0; i < 3; i++ )
|
|
||||||
{
|
|
||||||
QLinearGradient myGradient( {width() / 2, 0}, {width() / 2, height()} );
|
|
||||||
myGradient.setColorAt( 0, colors[i].first );
|
|
||||||
myGradient.setColorAt( 1, colors[i].second );
|
|
||||||
QPen myPen( Qt::transparent );
|
|
||||||
|
|
||||||
QPainterPath myPath;
|
|
||||||
myPath.moveTo( 0, height() );
|
|
||||||
myPath.lineTo( 0, 50 );
|
|
||||||
|
|
||||||
qreal stepSize = width() / segments;
|
|
||||||
|
|
||||||
for( int j = 1; j < segments; j++ )
|
|
||||||
{
|
|
||||||
qreal x1 = j * stepSize + stepSize / 2;
|
|
||||||
qreal y = ( 1 - yValues[i][j] ) * height();
|
|
||||||
myPath.lineTo( x1, y );
|
|
||||||
}
|
|
||||||
|
|
||||||
myPath.lineTo( width(), ( 1 - yValues[i][7] ) * height() );
|
|
||||||
myPath.lineTo( width(), height() );
|
|
||||||
|
|
||||||
QPainterPath smoothPath = smoothOut( myPath );
|
|
||||||
smoothPath.lineTo( width(), height() );
|
|
||||||
painter->setBrush( myGradient );
|
|
||||||
painter->setPen( myPen );
|
|
||||||
painter->drawPath( smoothPath );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "Diagram.moc"
|
#include "Diagram.moc"
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <QQuickPaintedItem>
|
#include <QQuickPaintedItem>
|
||||||
|
|
||||||
|
class Diagram;
|
||||||
class DiagramContent;
|
class DiagramContent;
|
||||||
class QskGridBox;
|
class QskGridBox;
|
||||||
|
|
||||||
|
@ -128,7 +129,6 @@ class UsageDiagram : public Box
|
||||||
QSK_SUBCONTROLS( Panel )
|
QSK_SUBCONTROLS( Panel )
|
||||||
|
|
||||||
UsageDiagram( QQuickItem* parent );
|
UsageDiagram( QQuickItem* parent );
|
||||||
void updateLayout() override;
|
|
||||||
|
|
||||||
QskAspect::Subcontrol effectiveSubcontrol(
|
QskAspect::Subcontrol effectiveSubcontrol(
|
||||||
QskAspect::Subcontrol subControl ) const override final
|
QskAspect::Subcontrol subControl ) const override final
|
||||||
|
@ -142,20 +142,9 @@ class UsageDiagram : public Box
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Diagram* m_diagram;
|
||||||
QskLinearBox* m_captionBox;
|
QskLinearBox* m_captionBox;
|
||||||
QskGridBox* m_weekdays;
|
QskGridBox* m_weekdays;
|
||||||
DiagramContent* m_content;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DiagramContent : public QQuickPaintedItem
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
DiagramContent( QQuickItem* parent );
|
|
||||||
|
|
||||||
virtual void paint( QPainter* painter ) override;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // USAGEDIAGRAM_H
|
#endif // USAGEDIAGRAM_H
|
||||||
|
|
|
@ -49,8 +49,19 @@ void IdlChartNode::update( const QRectF& rect, Type type, const QColor& color, c
|
||||||
m_geometry.allocate( vertexCount );
|
m_geometry.allocate( vertexCount );
|
||||||
auto vertexData = m_geometry.vertexDataAsPoint2D();
|
auto vertexData = m_geometry.vertexDataAsPoint2D();
|
||||||
|
|
||||||
const qreal xMin = m_dataPoints.at( 0 ).x();
|
qreal xMin;
|
||||||
const qreal xMax = m_dataPoints.at( m_dataPoints.count() - 1 ).x();
|
qreal xMax;
|
||||||
|
|
||||||
|
if( m_dataPoints.count() > 0 )
|
||||||
|
{
|
||||||
|
xMin = m_dataPoints.at( 0 ).x();
|
||||||
|
xMax = m_dataPoints.at( m_dataPoints.count() - 1 ).x();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xMin = 0;
|
||||||
|
xMax = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// ### we should have a different function for each chart type
|
// ### we should have a different function for each chart type
|
||||||
for( int i = 0; i < m_dataPoints.size(); ++i )
|
for( int i = 0; i < m_dataPoints.size(); ++i )
|
||||||
|
|
Loading…
Reference in New Issue