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 }
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:180
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:26
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-2021 The KDE developers.
Generated on Sun Sep 19 2021 22:37:22 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.