KChart

KChartTernaryAxis.cpp
1 /*
2  * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3  *
4  * This file is part of the KD Chart library.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #include "KChartTernaryAxis.h"
21 
22 #include <QPainter>
23 
24 #include <KChartChart.h>
25 #include <KChartPaintContext.h>
26 
27 #include "TernaryConstants.h"
28 #include "KChartTernaryCoordinatePlane.h"
29 #include "KChartAbstractTernaryDiagram.h"
30 
31 
32 #include "KChartLayoutItems.h"
33 #include "KChartTextLabelCache.h"
34 
35 using namespace KChart;
36 
37 // m_label and m_fifty do not have to be pointers, once the class is
38 // pimpled (PrerenderedLabel is not published API)
39 
40 TernaryAxis::TernaryAxis ( AbstractTernaryDiagram* diagram)
41  : AbstractAxis( diagram )
42  , m_position( KChartEnums::PositionUnknown )
43  , m_label( new PrerenderedLabel )
44  , m_fifty( new PrerenderedLabel )
45 {
46  resetTitleTextAttributes();
47  setPosition( KChartEnums::PositionSouth ); // arbitrary
48  m_fifty->setText( QObject::tr( "50%" ) ); // const
49  // FIXME is this consistent with other diagram/axis/plane implementations?
50  diagram->addAxis( this );
51 }
52 
53 TernaryAxis::~TernaryAxis()
54 {
55  delete m_label; m_label = nullptr;
56  delete m_fifty; m_fifty = nullptr;
57 }
58 
60 {
61  // not used
62 }
63 
64 void TernaryAxis::paint (QPainter *)
65 {
66  // not used
67 }
68 
69 void TernaryAxis::paintCtx (PaintContext * paintContext)
70 {
71  QPainter* p = paintContext->painter();
72  TernaryCoordinatePlane* plane =
73  (TernaryCoordinatePlane*) paintContext->coordinatePlane();
74  // QObject* refArea = plane->parent();
75 
76  // paint the axis label (across the triangle, that one):
78  labels << m_label << m_fifty;
79  for ( PrerenderedLabel* label : qAsConst(labels) ) {
80  const QPixmap& pixmap = label->pixmap();
81  const QPointF point = plane->translate( label->position() )
82  - label->referencePointLocation();
83  p->drawPixmap( point, pixmap );
84  }
85 }
86 
87 bool TernaryAxis::isEmpty() const
88 {
89  // todo: what's this method for?
90  return false;
91 }
92 
93 QRect TernaryAxis::geometry () const
94 {
95  return m_geometry;
96 }
97 
98 void TernaryAxis::setGeometry (const QRect &rect)
99 {
100  m_geometry = rect;
101 }
102 
103 QSize TernaryAxis::minimumSize () const
104 {
105  // todo: return realistic sizes
106  return QSize( 100, 100 );
107 }
108 
109 QSize TernaryAxis::maximumSize () const
110 {
111  return QSize( 300, 200 );
112 }
113 
114 QSize TernaryAxis::sizeHint () const
115 {
116  return QSize( 150, 100 );
117 }
118 
119 Qt::Orientations TernaryAxis::expandingDirections () const
120 {
121  return Qt::Vertical | Qt::Horizontal;
122 }
123 
124 const Position TernaryAxis::position () const
125 {
126  return m_position;
127 }
128 
129 void TernaryAxis::setPosition (Position p)
130 {
131  if ( p == position() ) return;
132 
133  if ( p != KChartEnums::PositionWest
134  && p != KChartEnums::PositionEast
135  && p != KChartEnums::PositionSouth )
136  {
137  qDebug() << "TernaryAxis::setPosition: only south, east and west are supported "
138  "positions for ternary axes.";
139  return;
140  }
141 
142  if ( m_title.isEmpty() )
143  switch ( p.value() ) {
144  case KChartEnums::PositionSouth:
145  m_label->setText( tr( "A" ) );
146  break;
147  case KChartEnums::PositionWest:
148  m_label->setText( tr( "C" ) );
149  break;
150  case KChartEnums::PositionEast:
151  m_label->setText( tr( "B" ) );
152  break;
153  default:
154  break;
155  }
156 
157  m_position = p;
158  updatePrerenderedLabels(); // position has changed
159 }
160 
161 void TernaryAxis::setTitleText( const QString& text )
162 {
163  m_title = text; // do not remove
164  m_label->setText( text );
165 }
166 
167 QString TernaryAxis::titleText() const
168 {
169  return m_label->text();
170 }
171 
172 void TernaryAxis::setTitleTextAttributes( const TextAttributes &a )
173 {
174  m_titleAttributes = a;
175  updatePrerenderedLabels();
176 }
177 
178 TextAttributes TernaryAxis::titleTextAttributes() const
179 {
180  return m_titleAttributes;
181 }
182 
183 void TernaryAxis::resetTitleTextAttributes()
184 {
185  TextAttributes a;
186  m_titleAttributes = a;
187  updatePrerenderedLabels();
188 }
189 
190 bool TernaryAxis::hasDefaultTitleTextAttributes() const
191 {
192  TextAttributes a;
193  return m_titleAttributes == a;
194 }
195 
196 void TernaryAxis::updatePrerenderedLabels()
197 {
198  TextAttributes attributes = titleTextAttributes();
199  qreal axisLabelAngle = 0.0;
200  qreal fiftyMarkAngle = 0.0;
201  QPointF axisLabelPosition;
202  QPointF fiftyMarkPosition;
203  KChartEnums::PositionValue fiftyMarkReferencePoint = KChartEnums::PositionUnknown;
204 
205  switch ( position().value() ) {
206  case KChartEnums::PositionSouth:
207  // this is the axis on the other side of A
208  axisLabelAngle = 0.0;
209  fiftyMarkAngle = 0.0;
210  axisLabelPosition = TriangleTop;
211  fiftyMarkPosition = 0.5 * AxisVector_B_C - RelMarkerLength * Norm_B_C;
212  fiftyMarkReferencePoint = KChartEnums::PositionNorth;
213  break;
214  case KChartEnums::PositionEast:
215  // this is the axis on the other side of B
216  axisLabelAngle = 240.0;
217  fiftyMarkAngle = 60;
218  axisLabelPosition = TriangleBottomLeft;
219  fiftyMarkPosition = AxisVector_B_C + 0.5 * AxisVector_C_A - RelMarkerLength * Norm_C_A;
220  fiftyMarkReferencePoint = KChartEnums::PositionSouth;
221  break;
222  case KChartEnums::PositionWest:
223  // this is the axis on the other side of C
224  axisLabelAngle = 120.0;
225  fiftyMarkAngle = 300.0;
226  axisLabelPosition = TriangleBottomRight;
227  fiftyMarkPosition = 0.5 * AxisVector_B_A + RelMarkerLength * Norm_B_A;
228  fiftyMarkReferencePoint = KChartEnums::PositionSouth;
229  break;
230  case KChartEnums::PositionUnknown:
231  break; // initial value
232  default:
233  qDebug() << "TernaryAxis::updatePrerenderedLabel: unknown location";
234  };
235 
236  m_label->setFont( attributes.font() );
237  // m_label->setText( titleText() ); // done by setTitleText()
238  m_label->setAngle( axisLabelAngle );
239  m_label->setPosition( axisLabelPosition );
240  m_label->setReferencePoint( KChartEnums::PositionSouth );
241  QFont font = attributes.font();
242  font.setPointSizeF( 0.85 * font.pointSizeF() );
243  m_fifty->setFont( font );
244  m_fifty->setAngle( fiftyMarkAngle );
245  m_fifty->setPosition( fiftyMarkPosition );
246  m_fifty->setReferencePoint( fiftyMarkReferencePoint );
247 }
248 
249 QPair<QSizeF, QSizeF> TernaryAxis::requiredMargins() const
250 {
251  QSizeF topleft( 0.0, 0.0 );
252  QSizeF bottomRight( 0.0, 0.0 );
253 
254  switch ( position().value() ) {
255  case KChartEnums::PositionSouth:
256  // the label of the south axis is, in fact, up north.
257  topleft.setHeight( m_label->pixmap().height() );
258  bottomRight.setHeight( m_fifty->pixmap().height() );
259  break;
260  case KChartEnums::PositionWest:
261  bottomRight.setWidth( m_label->pixmap().width()
262  - m_label->referencePointLocation().x() );
263  bottomRight.setHeight( m_label->pixmap().height()
264  - m_label->referencePointLocation().y() );
265  break;
266  case KChartEnums::PositionEast:
267  topleft.setWidth( m_label->pixmap().width()
268  - ( m_label->pixmap().width()
269  - m_label->referencePointLocation().x() ) );
270  bottomRight.setHeight( m_label->pixmap().height()
271  - ( m_label->pixmap().height()
272  - m_label->referencePointLocation().y() ) );
273  break;
274  default:
275  qDebug() << "TernaryAxis::requiredMargins: unknown location";
276  }
277 // qDebug() << "TernaryAxis::requiredMargins:" << topleft << bottomRight;
278  return QPair<QSizeF, QSizeF>( topleft, bottomRight );
279 }
KChartEnums::PositionValue value() const
Returns an integer value corresponding to this Position.
PositionValue
Numerical values of the static KChart::Position instances, for using a Position::value() with a switc...
Definition: KChartEnums.h:189
qreal pointSizeF() const const
Defines a position, using compass terminology.
const QPointF translate(const QPointF &diagramPoint) const override
Translate the given point in value space coordinates to a position in pixel space.
QString tr(const char *sourceText, const char *disambiguation, int n)
Project global class providing some enums needed both by KChartParams and by KChartCustomBox.
Definition: KChartEnums.h:37
Stores information about painting diagrams.
void setWidth(qreal width)
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
The base class for axes.
Base class for diagrams based on a ternary coordinate plane.
void paintCtx(PaintContext *) override
Default impl: Paint the complete item using its layouted position and size.
PrerenderedLabel is an internal KChart class that simplifies creation and caching of cached text labe...
void setPointSizeF(qreal pointSize)
void paintAll(QPainter &) override
Call paintAll, if you want the background and the frame to be drawn before the normal paint() is invo...
A set of text attributes.
typedef Orientations
Global namespace.
void setHeight(qreal height)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Thu Sep 17 2020 22:36:40 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.