Add Diagram drawn with OpenGL
This commit is contained in:
parent
0c08aca07f
commit
0df95fcb37
|
@ -0,0 +1,94 @@
|
||||||
|
#include "Diagram.h"
|
||||||
|
|
||||||
|
#include <QVectorIterator>
|
||||||
|
|
||||||
|
class Diagram::PrivateData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PrivateData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QPointF> dataPoints;
|
||||||
|
int xGridLines = -1;
|
||||||
|
qreal yMax = -1;
|
||||||
|
Qsk::Position position = Qsk::Bottom;
|
||||||
|
Types types = Area;
|
||||||
|
};
|
||||||
|
|
||||||
|
QSK_SUBCONTROL( Diagram, Chart )
|
||||||
|
QSK_SUBCONTROL( Diagram, Segments )
|
||||||
|
QSK_SUBCONTROL( Diagram, ChartLine )
|
||||||
|
QSK_SUBCONTROL( Diagram, ChartArea )
|
||||||
|
|
||||||
|
Diagram::Diagram( QQuickItem* parent )
|
||||||
|
: Inherited( parent )
|
||||||
|
, m_data( new PrivateData() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Diagram::~Diagram()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QPointF> Diagram::dataPoints() const
|
||||||
|
{
|
||||||
|
return m_data->dataPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Diagram::setDataPoints( const QVector<QPointF>& dataPoints )
|
||||||
|
{
|
||||||
|
m_data->dataPoints = dataPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
Diagram::Types Diagram::types() const
|
||||||
|
{
|
||||||
|
return m_data->types;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Diagram::setTypes( Types types )
|
||||||
|
{
|
||||||
|
m_data->types = types;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal Diagram::yMax() const
|
||||||
|
{
|
||||||
|
return m_data->yMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Diagram::setYMax( qreal yMax )
|
||||||
|
{
|
||||||
|
m_data->yMax = yMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Diagram::xGridLines() const
|
||||||
|
{
|
||||||
|
return m_data->xGridLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Diagram::setXGridLines( int lines )
|
||||||
|
{
|
||||||
|
m_data->xGridLines = lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qsk::Position Diagram::chartPosition() const
|
||||||
|
{
|
||||||
|
return m_data->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Diagram::setChartPosition( Qsk::Position position )
|
||||||
|
{
|
||||||
|
m_data->position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF Diagram::contentsSizeHint( Qt::SizeHint which, const QSizeF& ) const
|
||||||
|
{
|
||||||
|
if( which != Qt::PreferredSize )
|
||||||
|
{
|
||||||
|
return QSizeF();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_Diagram.cpp"
|
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QskControl.h>
|
||||||
|
#include <QskNamespace.h>
|
||||||
|
|
||||||
|
class Diagram : public QskControl
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
using Inherited = QskControl;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QSK_SUBCONTROLS( Chart, Segments, ChartLine, ChartArea )
|
||||||
|
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
Line = 0x01,
|
||||||
|
Area = 0x02,
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_FLAGS( Types, Type )
|
||||||
|
|
||||||
|
Diagram( QQuickItem* parent = nullptr );
|
||||||
|
~Diagram() override;
|
||||||
|
|
||||||
|
QVector<QPointF> dataPoints() const;
|
||||||
|
void setDataPoints( const QVector<QPointF>& dataPoints );
|
||||||
|
|
||||||
|
Types types() const;
|
||||||
|
void setTypes( Types types );
|
||||||
|
|
||||||
|
qreal yMax() const;
|
||||||
|
void setYMax( qreal yMax );
|
||||||
|
|
||||||
|
int xGridLines() const;
|
||||||
|
void setXGridLines( int lines );
|
||||||
|
|
||||||
|
Qsk::Position chartPosition() const;
|
||||||
|
void setChartPosition( Qsk::Position position );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QSizeF contentsSizeHint( Qt::SizeHint, const QSizeF& ) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class PrivateData;
|
||||||
|
std::unique_ptr< PrivateData > m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS( Diagram::Types )
|
|
@ -0,0 +1,125 @@
|
||||||
|
#include "DiagramSkinlet.h"
|
||||||
|
#include "Diagram.h"
|
||||||
|
#include "nodes/DiagramDataNode.h"
|
||||||
|
#include "nodes/DiagramSegmentsNode.h"
|
||||||
|
|
||||||
|
DiagramSkinlet::DiagramSkinlet( QskSkin* skin )
|
||||||
|
: QskSkinlet( skin )
|
||||||
|
{
|
||||||
|
setNodeRoles( { ChartRole, SeparatorRole } );
|
||||||
|
}
|
||||||
|
|
||||||
|
DiagramSkinlet::~DiagramSkinlet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF DiagramSkinlet::subControlRect(
|
||||||
|
const QskSkinnable* skinnable, const QRectF& contentsRect,
|
||||||
|
QskAspect::Subcontrol subControl ) const
|
||||||
|
{
|
||||||
|
if( subControl == Diagram::Chart )
|
||||||
|
{
|
||||||
|
return contentsRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Inherited::subControlRect( skinnable, contentsRect, subControl );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGNode* DiagramSkinlet::updateSubNode(
|
||||||
|
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
|
||||||
|
{
|
||||||
|
const auto discharge = static_cast< const Diagram* >( skinnable );
|
||||||
|
|
||||||
|
switch( nodeRole )
|
||||||
|
{
|
||||||
|
case ChartRole:
|
||||||
|
{
|
||||||
|
return updateChartNode( discharge, node );
|
||||||
|
}
|
||||||
|
|
||||||
|
case SeparatorRole:
|
||||||
|
{
|
||||||
|
return updateSeparatorNode( discharge, node );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGNode* DiagramSkinlet::updateChartNode( const Diagram* distribution, QSGNode* node ) const
|
||||||
|
{
|
||||||
|
if( node == nullptr )
|
||||||
|
{
|
||||||
|
node = new IdlChartNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
QVector<Diagram::Type> types = {Diagram::Line, Diagram::Area};
|
||||||
|
|
||||||
|
int nodeIndex = 0;
|
||||||
|
|
||||||
|
for( int i = 0; i < types.size(); ++i )
|
||||||
|
{
|
||||||
|
if( distribution->types() & types.at( i ) )
|
||||||
|
{
|
||||||
|
IdlChartNode* lineNode;
|
||||||
|
|
||||||
|
if( node->childCount() > nodeIndex )
|
||||||
|
{
|
||||||
|
lineNode = static_cast<IdlChartNode*>( node->childAtIndex( nodeIndex ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lineNode = new IdlChartNode;
|
||||||
|
node->appendChildNode( lineNode );
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
|
||||||
|
lineNode->update( rect, nodeType, color, dataPoints, yMax, position, lineWidth );
|
||||||
|
nodeIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while( nodeIndex < node->childCount() )
|
||||||
|
{
|
||||||
|
node->removeChildNode( node->childAtIndex( nodeIndex++ ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGNode* DiagramSkinlet::updateSeparatorNode( const Diagram* discharge, QSGNode* node ) const
|
||||||
|
{
|
||||||
|
const int xGridLines = discharge->xGridLines();
|
||||||
|
|
||||||
|
if( xGridLines <= 0 )
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* separatorNode = static_cast<IdlChartSegmentsNode*>( node );
|
||||||
|
|
||||||
|
if( separatorNode == nullptr )
|
||||||
|
{
|
||||||
|
separatorNode = new IdlChartSegmentsNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
using Q = Diagram;
|
||||||
|
const QRectF rect = discharge->subControlRect( Q::Chart );
|
||||||
|
const QColor color = discharge->color( Q::Segments );
|
||||||
|
const QVector<QPointF> dataPoints = discharge->dataPoints();
|
||||||
|
|
||||||
|
separatorNode->update( rect, color, dataPoints, xGridLines );
|
||||||
|
|
||||||
|
return separatorNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_DiagramSkinlet.cpp"
|
|
@ -0,0 +1,34 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QskSkinlet.h>
|
||||||
|
|
||||||
|
class Diagram;
|
||||||
|
|
||||||
|
class DiagramSkinlet : public QskSkinlet
|
||||||
|
{
|
||||||
|
Q_GADGET
|
||||||
|
|
||||||
|
using Inherited = QskSkinlet;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum NodeRole
|
||||||
|
{
|
||||||
|
ChartRole,
|
||||||
|
SeparatorRole,
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_INVOKABLE DiagramSkinlet( QskSkin* = nullptr );
|
||||||
|
~DiagramSkinlet() override;
|
||||||
|
|
||||||
|
QRectF subControlRect( const QskSkinnable*,
|
||||||
|
const QRectF&, QskAspect::Subcontrol ) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
QSGNode* updateSubNode( const QskSkinnable*,
|
||||||
|
quint8 nodeRole, QSGNode* ) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSGNode* updateChartNode( const Diagram*, QSGNode* ) const;
|
||||||
|
QSGNode* updateSeparatorNode( const Diagram*, QSGNode* ) const;
|
||||||
|
};
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "Box.h"
|
#include "Box.h"
|
||||||
#include "BoxWithButtons.h"
|
#include "BoxWithButtons.h"
|
||||||
#include "Diagram.h"
|
|
||||||
#include "LightIntensity.h"
|
#include "LightIntensity.h"
|
||||||
#include "MainContent.h"
|
#include "MainContent.h"
|
||||||
#include "MenuBar.h"
|
#include "MenuBar.h"
|
||||||
|
@ -10,6 +9,7 @@
|
||||||
#include "TopBar.h"
|
#include "TopBar.h"
|
||||||
#include "UpAndDownButton.h"
|
#include "UpAndDownButton.h"
|
||||||
#include "Usage.h"
|
#include "Usage.h"
|
||||||
|
#include "UsageDiagram.h"
|
||||||
|
|
||||||
#include <QskBoxBorderMetrics.h>
|
#include <QskBoxBorderMetrics.h>
|
||||||
#include <QskBoxBorderColors.h>
|
#include <QskBoxBorderColors.h>
|
||||||
|
|
|
@ -4,7 +4,8 @@ SOURCES += \
|
||||||
Box.cpp \
|
Box.cpp \
|
||||||
BoxWithButtons.cpp \
|
BoxWithButtons.cpp \
|
||||||
CircularProgressBar.cpp \
|
CircularProgressBar.cpp \
|
||||||
UsageDiagram.cpp \
|
Diagram.cpp \
|
||||||
|
DiagramSkinlet.cpp \
|
||||||
LightIntensity.cpp \
|
LightIntensity.cpp \
|
||||||
MainContent.cpp \
|
MainContent.cpp \
|
||||||
MenuBar.cpp \
|
MenuBar.cpp \
|
||||||
|
@ -18,13 +19,19 @@ SOURCES += \
|
||||||
UpAndDownButton.cpp \
|
UpAndDownButton.cpp \
|
||||||
Usage.cpp \
|
Usage.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
MainWindow.cpp
|
MainWindow.cpp \
|
||||||
|
UsageDiagram.cpp
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
nodes/DiagramDataNode.cpp \
|
||||||
|
nodes/DiagramSegmentsNode.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
Box.h \
|
Box.h \
|
||||||
BoxWithButtons.h \
|
BoxWithButtons.h \
|
||||||
CircularProgressBar.h \
|
CircularProgressBar.h \
|
||||||
UsageDiagram.h \
|
Diagram.h \
|
||||||
|
DiagramSkinlet.h \
|
||||||
LightIntensity.h \
|
LightIntensity.h \
|
||||||
MainContent.h \
|
MainContent.h \
|
||||||
MainWindow.h \
|
MainWindow.h \
|
||||||
|
@ -37,7 +44,12 @@ HEADERS += \
|
||||||
Skin.h \
|
Skin.h \
|
||||||
TopBar.h \
|
TopBar.h \
|
||||||
UpAndDownButton.h \
|
UpAndDownButton.h \
|
||||||
Usage.h
|
Usage.h \
|
||||||
|
UsageDiagram.h
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
nodes/DiagramDataNode.h \
|
||||||
|
nodes/DiagramSegmentsNode.h
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/shadowedrectangle.h \
|
src/shadowedrectangle.h \
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include "DiagramDataNode.h"
|
||||||
|
#include <QTransform>
|
||||||
|
#include <QskFunctions.h>
|
||||||
|
|
||||||
|
IdlChartNode::IdlChartNode()
|
||||||
|
: m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
|
||||||
|
{
|
||||||
|
setGeometry( &m_geometry );
|
||||||
|
setMaterial( &m_material );
|
||||||
|
}
|
||||||
|
|
||||||
|
void IdlChartNode::update( const QRectF& rect, Type type, const QColor& color, const QVector<QPointF>& dataPoints,
|
||||||
|
const qreal yMax, Qsk::Position position, int lineWidth )
|
||||||
|
{
|
||||||
|
Q_UNUSED( rect );
|
||||||
|
|
||||||
|
if( color != m_color )
|
||||||
|
{
|
||||||
|
m_material.setColor( color );
|
||||||
|
m_color = color;
|
||||||
|
markDirty( QSGNode::DirtyMaterial );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_rect == rect && m_dataPoints == dataPoints && m_yMax == yMax && m_position == position
|
||||||
|
&& m_type == type && m_lineWidth == lineWidth )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( lineWidth != m_lineWidth )
|
||||||
|
{
|
||||||
|
m_lineWidth = lineWidth;
|
||||||
|
m_geometry.setLineWidth( lineWidth );
|
||||||
|
|
||||||
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rect = rect;
|
||||||
|
m_dataPoints = dataPoints;
|
||||||
|
m_yMax = yMax;
|
||||||
|
m_position = position;
|
||||||
|
m_type = type;
|
||||||
|
|
||||||
|
GLenum drawingMode = ( m_type == Line ) ? GL_LINES : GL_TRIANGLE_STRIP;
|
||||||
|
m_geometry.setDrawingMode( drawingMode );
|
||||||
|
|
||||||
|
const int vertexCount = ( m_type == Line ) ? m_dataPoints.size() * 2 - 1 : m_dataPoints.size() * 2;
|
||||||
|
|
||||||
|
m_geometry.allocate( vertexCount );
|
||||||
|
auto vertexData = m_geometry.vertexDataAsPoint2D();
|
||||||
|
|
||||||
|
const qreal xMin = m_dataPoints.at( 0 ).x();
|
||||||
|
const qreal xMax = m_dataPoints.at( m_dataPoints.count() - 1 ).x();
|
||||||
|
|
||||||
|
// ### we should have a different function for each chart type
|
||||||
|
for( int i = 0; i < m_dataPoints.size(); ++i )
|
||||||
|
{
|
||||||
|
const qreal x = ( ( m_dataPoints.at( i ).x() - xMin ) / ( xMax - xMin ) ) * rect.width();
|
||||||
|
const qreal fraction = ( m_dataPoints.at( i ).y() / yMax ) * rect.height();
|
||||||
|
const qreal y = ( position == Qsk::Top ) ? fraction : rect.height() - fraction;
|
||||||
|
|
||||||
|
if( m_type == Line && i < m_dataPoints.size() - 1 )
|
||||||
|
{
|
||||||
|
const qreal x2 = ( ( m_dataPoints.at( i + 1 ).x() - xMin ) / ( xMax - xMin ) ) * rect.width();
|
||||||
|
const qreal fraction2 = ( m_dataPoints.at( i + 1 ).y() / yMax ) * rect.height();
|
||||||
|
const qreal y2 = ( position == Qsk::Top ) ? fraction2 : rect.height() - fraction2;
|
||||||
|
vertexData[2 * i].x = x;
|
||||||
|
vertexData[2 * i].y = y;
|
||||||
|
|
||||||
|
vertexData[2 * i + 1].x = x2;
|
||||||
|
vertexData[2 * i + 1].y = y2;
|
||||||
|
}
|
||||||
|
else if( m_type == Area )
|
||||||
|
{
|
||||||
|
const qreal y0 = ( position == Qsk::Top ) ? 0 : rect.height();
|
||||||
|
vertexData[2 * i].x = x;
|
||||||
|
vertexData[2 * i].y = y;
|
||||||
|
|
||||||
|
vertexData[2 * i + 1].x = x;
|
||||||
|
vertexData[2 * i + 1].y = y0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QskNamespace.h>
|
||||||
|
|
||||||
|
#include <QPolygonF>
|
||||||
|
#include <QSGFlatColorMaterial>
|
||||||
|
#include <QSGGeometryNode>
|
||||||
|
|
||||||
|
class IdlChartNode : public QSGGeometryNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
Line,
|
||||||
|
Area,
|
||||||
|
};
|
||||||
|
|
||||||
|
IdlChartNode();
|
||||||
|
|
||||||
|
void update( const QRectF& rect, Type type, const QColor& color, const QVector<QPointF>& dataPoints, const qreal yMax, Qsk::Position position, int lineWidth );
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSGFlatColorMaterial m_material;
|
||||||
|
QSGGeometry m_geometry;
|
||||||
|
|
||||||
|
QRectF m_rect;
|
||||||
|
Type m_type;
|
||||||
|
QColor m_color;
|
||||||
|
QVector<QPointF> m_dataPoints;
|
||||||
|
qreal m_yMax;
|
||||||
|
Qsk::Position m_position;
|
||||||
|
int m_lineWidth;
|
||||||
|
};
|
|
@ -0,0 +1,51 @@
|
||||||
|
#include "DiagramSegmentsNode.h"
|
||||||
|
|
||||||
|
#include <QtMath>
|
||||||
|
|
||||||
|
IdlChartSegmentsNode::IdlChartSegmentsNode()
|
||||||
|
: m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
|
||||||
|
{
|
||||||
|
m_geometry.setDrawingMode( GL_LINES );
|
||||||
|
|
||||||
|
setGeometry( &m_geometry );
|
||||||
|
setMaterial( &m_material );
|
||||||
|
}
|
||||||
|
|
||||||
|
void IdlChartSegmentsNode::update( const QRectF& rect, const QColor& color, const QVector<QPointF>& dataPoints, int xGridLines )
|
||||||
|
{
|
||||||
|
Q_UNUSED( rect );
|
||||||
|
|
||||||
|
if( color != m_color )
|
||||||
|
{
|
||||||
|
m_material.setColor( color );
|
||||||
|
m_color = color;
|
||||||
|
markDirty( QSGNode::DirtyMaterial );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_rect == rect && m_dataPoints == dataPoints && m_xGridLines == xGridLines )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rect = rect;
|
||||||
|
m_dataPoints = dataPoints;
|
||||||
|
m_xGridLines = xGridLines;
|
||||||
|
|
||||||
|
const qreal step = rect.width() / ( xGridLines - 1 );
|
||||||
|
|
||||||
|
m_geometry.allocate( m_xGridLines * 2 );
|
||||||
|
auto vertexData = m_geometry.vertexDataAsPoint2D();
|
||||||
|
|
||||||
|
for( int i = 0; i < m_xGridLines; ++i )
|
||||||
|
{
|
||||||
|
const qreal x = i * step;
|
||||||
|
|
||||||
|
vertexData[2 * i].x = x;
|
||||||
|
vertexData[2 * i].y = rect.height();
|
||||||
|
|
||||||
|
vertexData[2 * i + 1].x = x;
|
||||||
|
vertexData[2 * i + 1].y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QPolygonF>
|
||||||
|
#include <QSGFlatColorMaterial>
|
||||||
|
#include <QSGGeometryNode>
|
||||||
|
|
||||||
|
class IdlChartSegmentsNode : public QSGGeometryNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
IdlChartSegmentsNode();
|
||||||
|
|
||||||
|
void update( const QRectF& rect, const QColor& color, const QVector<QPointF>& dataPoints, int xGridLines );
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSGFlatColorMaterial m_material;
|
||||||
|
QSGGeometry m_geometry;
|
||||||
|
|
||||||
|
QRectF m_rect;
|
||||||
|
QColor m_color;
|
||||||
|
QVector<QPointF> m_dataPoints;
|
||||||
|
int m_xGridLines;
|
||||||
|
};
|
Loading…
Reference in New Issue