2021-04-26 06:22:35 +02:00
|
|
|
/******************************************************************************
|
2023-04-06 09:23:37 +02:00
|
|
|
* Copyright (C) 2021 Edelhirsch Software GmbH
|
|
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
2021-04-26 06:22:35 +02:00
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "DiagramDataNode.h"
|
|
|
|
#include <QTransform>
|
|
|
|
#include <QskFunctions.h>
|
|
|
|
|
|
|
|
DiagramDataNode::DiagramDataNode()
|
|
|
|
: m_geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
|
|
|
|
{
|
|
|
|
setGeometry( &m_geometry );
|
|
|
|
setMaterial( &m_material );
|
|
|
|
}
|
|
|
|
|
2021-08-04 09:31:16 +02:00
|
|
|
void DiagramDataNode::update( const QRectF& rect, Type type,
|
|
|
|
const QColor& color, const QVector< QPointF >& dataPoints,
|
2022-04-17 12:25:51 +02:00
|
|
|
const qreal yMax, bool inverted, int lineWidth )
|
2021-04-26 06:22:35 +02:00
|
|
|
{
|
|
|
|
if( color != m_color )
|
|
|
|
{
|
|
|
|
m_material.setColor( color );
|
|
|
|
m_color = color;
|
|
|
|
markDirty( QSGNode::DirtyMaterial );
|
|
|
|
}
|
|
|
|
|
2022-04-17 12:25:51 +02:00
|
|
|
if( m_rect == rect && m_dataPoints == dataPoints && m_yMax == yMax
|
|
|
|
&& m_inverted == inverted && m_type == type && m_lineWidth == lineWidth )
|
2021-04-26 06:22:35 +02:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( lineWidth != m_lineWidth )
|
|
|
|
{
|
|
|
|
m_lineWidth = lineWidth;
|
|
|
|
m_geometry.setLineWidth( lineWidth );
|
|
|
|
|
|
|
|
markDirty( QSGNode::DirtyGeometry );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_rect = rect;
|
|
|
|
m_dataPoints = dataPoints;
|
|
|
|
m_yMax = yMax;
|
2022-04-17 12:25:51 +02:00
|
|
|
m_inverted = inverted;
|
2021-04-26 06:22:35 +02:00
|
|
|
m_type = type;
|
|
|
|
|
2021-04-26 08:38:10 +02:00
|
|
|
const auto drawingMode =
|
|
|
|
( m_type == Line ) ? QSGGeometry::DrawLines : QSGGeometry::DrawTriangleStrip;
|
|
|
|
|
2021-04-26 06:22:35 +02:00
|
|
|
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();
|
|
|
|
|
|
|
|
qreal xMin;
|
|
|
|
qreal xMax;
|
|
|
|
|
|
|
|
if( m_dataPoints.count() > 0 )
|
|
|
|
{
|
2021-08-04 09:31:16 +02:00
|
|
|
xMin = m_dataPoints.at( 0 ).x();
|
2021-04-26 06:22:35 +02:00
|
|
|
xMax = m_dataPoints.at( m_dataPoints.count() - 1 ).x();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xMin = 0;
|
|
|
|
xMax = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ### 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();
|
2022-04-17 12:25:51 +02:00
|
|
|
const qreal y = inverted ? fraction : rect.height() - fraction;
|
2021-04-26 06:22:35 +02:00
|
|
|
|
|
|
|
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();
|
2022-04-17 12:25:51 +02:00
|
|
|
const qreal y2 = inverted ? fraction2 : rect.height() - fraction2;
|
2021-04-26 06:22:35 +02:00
|
|
|
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 )
|
|
|
|
{
|
2022-04-17 12:25:51 +02:00
|
|
|
const qreal y0 = inverted ? 0 : rect.height();
|
2021-04-26 06:22:35 +02:00
|
|
|
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 );
|
|
|
|
}
|