KChart

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

KDE's Doxygen guidelines are available online.