Revision control

Copy as Markdown

// Copyright (C) 2026 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
// Qt-Security score:significant reason:default
#include <QtGraphs/private/qgraphsglobal_p.h>
#if QT_CONFIG(graphs_2d_area)
#include <QtGraphs/private/arearenderer_p.h>
#endif
#if QT_CONFIG(graphs_2d_area) || QT_CONFIG(graphs_2d_line) || QT_CONFIG(graphs_2d_scatter) || QT_CONFIG(graphs_2d_spline)
#include <QtGraphs/private/pointrenderer_p.h>
#endif
#if QT_CONFIG(graphs_2d_high_performance_backend)
#include "qcpainteritem_p.h"
#endif
#include <QtGraphs/qbarcategoryaxis.h>
#include <QtGraphs/private/axisrenderer_p.h>
#include <QtGraphs/private/polaraxisrenderer_p.h>
#include "qpolarview_p.h"
QT_BEGIN_NAMESPACE
/*!
\qmltype PolarView
\nativetype QPolarView
\inqmlmodule QtGraphs
\ingroup graphs_qml_2D
\inherits GraphsView
\since 6.13
\brief Draws series on a polar coordinate system.
PolarView plots series on a polar coordinate system instead of the Cartesian
one that \l GraphsView uses. It reinterprets \l{GraphsView::axisX}{axisX} as
the angular axis and \l{GraphsView::axisY}{axisY} as the radial axis.
The angular axis maps its full range to one complete revolution, starting at
the top of the graph and advancing clockwise. The radial axis maps its
minimum to the center of the graph and its maximum to the outer edge. Values
below the radial minimum collapse onto the center.
PolarView supports \l LineSeries, \l ScatterSeries, \l SplineSeries, and
\l AreaSeries. Adding any other series type prints a warning and leaves the
graph unchanged. A polar view also rejects \l BarCategoryAxis and
\l ColorAxis.
The following example code illustrates how to use the PolarView type:
\qml
PolarView {
anchors.fill: parent
labelPadding: 12
axisX: ValueAxis { min: 0; max: 360 } // angular
axisY: ValueAxis { min: 0; max: 10 } // radial
LineSeries {
color: "#46f477"
width: 2
XYPoint { x: 0; y: 10 }
XYPoint { x: 120; y: 3 }
XYPoint { x: 240; y: 4 }
XYPoint { x: 360; y: 10 }
}
}
\endqml
The image below illustrates the result:
\image graphs2d-polarview.webp {A polar view with a single line series.}
\sa GraphsView, LineSeries, ScatterSeries, SplineSeries, AreaSeries,
ValueAxis
*/
QPolarView::QPolarView(QQuickItem *parent)
: QGraphsView(parent)
{
}
QPolarView::~QPolarView() = default;
bool QPolarView::isSeriesSupported(QObject *object) const
{
if (auto series = qobject_cast<QAbstractSeries *>(object)) {
switch (series->type()) {
case QAbstractSeries::SeriesType::Line:
case QAbstractSeries::SeriesType::Scatter:
case QAbstractSeries::SeriesType::Spline:
case QAbstractSeries::SeriesType::Area:
break;
case QAbstractSeries::SeriesType::Bar:
case QAbstractSeries::SeriesType::Pie:
case QAbstractSeries::SeriesType::Custom:
qWarning("Can not add series. Series type is not supported by a polar view.");
return false;
}
}
return QGraphsView::isSeriesSupported(object);
}
bool QPolarView::addAxis(QAbstractAxis *axis)
{
if (axis->type() == QAbstractAxis::AxisType::BarCategory) {
qWarning("QBarCategoryAxis is not a supported axis type for polar views.");
return false;
}
return QGraphsView::addAxis(axis);
}
void QPolarView::createAxisRenderer()
{
if (!m_axisRenderer) {
qCDebug(lcGraphs2D) << "creating polar axis renderer.";
m_axisRenderer = new PolarAxisRenderer(this);
m_axisRenderer->setZ(-1);
updateComponentSizes();
}
}
/*!
\qmlproperty point PolarView::polarCenter
\readonly
The center of the polar plot, in the coordinate space of the plot area.
Use this property together with \l polarRadius to position gradients or
custom items on top of the graph. The default value is \c{Qt.point(0, 0)}.
*/
QPointF QPolarView::polarCenter() const
{
return m_polarCenter;
}
/*!
\qmlproperty real PolarView::polarRadius
\readonly
The radius of the polar plot, in pixels.
The radius is half the side of the largest square that fits the plot area,
after subtracting the space that the radial axis labels need. The default
value is 0.
*/
qreal QPolarView::polarRadius() const
{
return m_polarRadius;
}
/*!
\qmlproperty real PolarView::labelPadding
The gap, in pixels, between the axis grid (the outer ring for angular
labels, or the ring belonging to a given tick for radial labels) and
the axis label items placed next to it. The default value is 8.
*/
qreal QPolarView::labelPadding() const
{
return m_labelPadding;
}
void QPolarView::setLabelPadding(qreal padding)
{
if (QtPrivate::fuzzyCompare(m_labelPadding, padding))
return;
m_labelPadding = qMax(qreal(0), padding);
polishAndUpdate();
emit labelPaddingChanged();
}
void QPolarView::updateComponentSizes()
{
qreal radialLabelBand = 0;
if (m_axisRenderer) {
m_axisRenderer->updateAxisMeasurements();
if (auto polarAxisRenderer = qobject_cast<PolarAxisRenderer*>(m_axisRenderer))
radialLabelBand = polarAxisRenderer->radialLabelBand();
}
qreal x = m_marginLeft;
qreal y = m_marginTop;
qreal w = width() - x - m_marginRight;
qreal h = height() - y - m_marginBottom;
qreal side = std::max(std::min(w, h) - radialLabelBand, 0.0);
qreal squareX = x + (w - side) / 2.0;
qreal squareY = y + (h - side) / 2.0;
QRectF plotArea = QRectF(squareX, squareY, side, side);
if (plotArea != m_plotArea) {
m_plotArea = plotArea;
emit plotAreaChanged();
}
qreal polarRadius = side / 2.0;
if (polarRadius != m_polarRadius) {
m_polarRadius = polarRadius;
emit polarRadiusChanged();
}
QPointF polarCenter(m_polarRadius, m_polarRadius);
if (polarCenter != m_polarCenter) {
m_polarCenter = polarCenter;
emit polarCenterChanged();
}
if (m_axisRenderer) {
m_axisRenderer->setX(m_plotArea.x());
m_axisRenderer->setY(m_plotArea.y());
m_axisRenderer->setSize(m_plotArea.size());
}
#if QT_CONFIG(graphs_2d_area) || QT_CONFIG(graphs_2d_line) || QT_CONFIG(graphs_2d_scatter) || QT_CONFIG(graphs_2d_spline)
if (m_pointRenderer) {
m_pointRenderer->setX(m_plotArea.x());
m_pointRenderer->setY(m_plotArea.y());
m_pointRenderer->setSize(m_plotArea.size());
}
#endif
#if QT_CONFIG(graphs_2d_area)
if (m_areaRenderer) {
m_areaRenderer->setX(m_plotArea.x());
m_areaRenderer->setY(m_plotArea.y());
m_areaRenderer->setSize(m_plotArea.size());
}
#endif
#if QT_CONFIG(graphs_2d_high_performance_backend)
if (m_painterItem) {
m_painterItem->setX(m_plotArea.x());
m_painterItem->setY(m_plotArea.y());
m_painterItem->setSize(m_plotArea.size());
}
#endif
}
QT_END_NAMESPACE
#include "moc_qpolarview_p.cpp"