KChart

KChartTernaryCoordinatePlane.cpp
1/*
2 * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3 *
4 * This file is part of the KD Chart library.
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9#include "KChartTernaryCoordinatePlane.h"
10#include "KChartTernaryCoordinatePlane_p.h"
11
12#include <QtDebug>
13#include <QPainter>
14
15#include "KChartPaintContext.h"
16#include "KChartPainterSaver_p.h"
17#include "KChartTernaryAxis.h"
18#include "KChartAbstractTernaryDiagram.h"
19
20#include "TernaryConstants.h"
21
22using namespace KChart;
23
24#define d d_func()
25
26TernaryCoordinatePlane::Private::Private()
27 : AbstractCoordinatePlane::Private()
28{
29}
30
31TernaryCoordinatePlane::TernaryCoordinatePlane( Chart* parent )
32 : AbstractCoordinatePlane( new Private(), parent )
33{
34}
35
36TernaryCoordinatePlane::~TernaryCoordinatePlane()
37{
38}
39
40void TernaryCoordinatePlane::init()
41{
42}
43
45{
46 Q_ASSERT_X ( dynamic_cast<AbstractTernaryDiagram*>( diagram ),
47 "TernaryCoordinatePlane::addDiagram", "Only ternary "
48 "diagrams can be added to a ternary coordinate plane!" );
50}
51
53{ // this is our "resize event":
54 // all diagrams always take the same space, nothing to be done here
55 // the "inner" margin (adjustments to diagram coordinates)
57 QSizeF( TriangleWidth, TriangleHeight ) );
58 QPair<QSizeF, QSizeF> margins = grid()->requiredMargins();
59 d->diagramRect = areaGeometry();
61 (-margins.first.width(), -margins.first.height(),
62 margins.second.width(), margins.second.height() );
63
64 // the "outer" margin (distance between diagram contents and area,
65 // determined by axis label overlap
66 {
67 QSizeF topleft( 0.0, 0.0 );
68 QSizeF bottomRight( 0.0, 0.0 );
69 const auto ds = diagrams();
74 const auto axes = diagram->axes();
75 for ( TernaryAxis* axis : axes ) {
76 QPair<QSizeF, QSizeF> margin = axis->requiredMargins();
77 topleft = topleft.expandedTo( margin.first );
78 bottomRight = bottomRight.expandedTo( margin.second );
79 }
80 }
81 d->diagramRectContainer =
82 d->diagramRect.adjusted( topleft.width(),
83 topleft.height(),
84 -bottomRight.width(),
85 -bottomRight.height() );
86 }
87
88 // now calculate isometric projection, x and y widget coordinate
89 // units, and location of (0.0, 0.0) in diagram coordinates
90 QPointF zeroZeroPoint = d->diagramRectContainer.bottomLeft();
91 qreal w = d->diagramRectContainer.width();
92 qreal h = d->diagramRectContainer.height();
93 qreal usableWidth;
94 qreal usableHeight;
95
96 if ( TriangleHeight * w > h ) {
97 // shorten width:
99 usableHeight = h;
100 zeroZeroPoint.setX( zeroZeroPoint.x() + ( w - usableWidth ) / 2 );
101 } else {
102 // reduce height:
103 usableWidth = w;
105 zeroZeroPoint.setY( zeroZeroPoint.y() - ( h - usableHeight ) / 2 );
106 }
107 // the rectangle has 1 as it's width, and TriangleHeight as it's
108 // height - so this is how we translate that to widget coordinates:
109 d->xUnit = usableWidth / diagramNativeRectangle.width(); // only because we normalize the values to [0..1]
110 d->yUnit = -usableHeight / diagramNativeRectangle.height();
111
112 // now move zeroZeroPoint so that it does not include the tick marks
113 {
114 qreal descent = diagramNativeRectangle.height() - TriangleHeight;
116 zeroZeroPoint += QPointF( rightShift * d->xUnit, descent * d->yUnit );
117 }
118
119 d->diagramRect.setBottomLeft( zeroZeroPoint );
120 d->diagramRect.setTopRight( QPointF( usableWidth, -usableHeight ) + zeroZeroPoint );
121}
122
124{
125 return QPointF( d->diagramRect.bottomLeft().x() + point.x() * d->xUnit,
126 d->diagramRect.bottomLeft().y() + point.y() * d->yUnit );
127}
128
130{
131 // FIXME temp
132 return QSize();
133}
134
140
141void TernaryCoordinatePlane::paint( QPainter* painter )
142{
143 PainterSaver s( painter );
144 // FIXME: this is not a good location for that:
145 painter->setRenderHint(QPainter::Antialiasing, true );
146
148 if ( !diags.isEmpty() )
149 {
151 ctx.setPainter ( painter );
152 ctx.setCoordinatePlane ( this );
153 const QRectF drawArea( areaGeometry() );
154 ctx.setRectangle ( drawArea );
155
156 // paint the coordinate system rulers:
157 Q_ASSERT( d->grid != nullptr );
158 d->grid->drawGrid( &ctx );
159
160 // paint the diagrams:
161 for ( int i = 0; i < diags.size(); i++ )
162 {
164 diags[i]->paint ( &ctx );
165 }
166 }
167}
168
169DataDimensionsList TernaryCoordinatePlane::getDataDimensionsList() const
170{ // not needed
171 return DataDimensionsList();
172}
173
174TernaryGrid* TernaryCoordinatePlane::grid() const
175{
176 TernaryGrid* ternaryGrid = static_cast<TernaryGrid*>( d->grid );
177 Q_ASSERT( dynamic_cast<TernaryGrid*>( d->grid ) );
178 return ternaryGrid;
179}
180
181#undef d
QRect areaGeometry() const override
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
virtual void addDiagram(AbstractDiagram *diagram)
Adds a diagram to this coordinate plane.
AbstractDiagram defines the interface for diagram classes.
Base class for diagrams based on a ternary coordinate plane.
Stores information about painting diagrams.
The class for ternary axes.
void layoutDiagrams() override
Distribute the available space among the diagrams and axes.
void addDiagram(AbstractDiagram *diagram) override
Adds a diagram to this coordinate plane.
const QPointF translate(const QPointF &diagramPoint) const override
Translate the given point in value space coordinates to a position in pixel space.
T qobject_cast(QObject *object)
void setRenderHint(RenderHint hint, bool on)
qreal x() const const
qreal y() const const
QSizeF expandedTo(const QSizeF &otherSize) const const
qreal height() const const
qreal width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:24 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.