KChart

KChartLeveyJenningsDiagram.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 "KChartLeveyJenningsDiagram.h"
10 #include "KChartLeveyJenningsDiagram_p.h"
11 
12 #include "KChartChart.h"
13 #include "KChartTextAttributes.h"
14 #include "KChartAbstractGrid.h"
15 #include "KChartPainterSaver_p.h"
16 
17 #include <QDateTime>
18 #include <QFontMetrics>
19 #include <QPainter>
20 #include <QSvgRenderer>
21 #include <QVector>
22 
23 using namespace KChart;
24 using namespace std;
25 
26 LeveyJenningsDiagram::Private::Private()
27 {
28 }
29 
30 LeveyJenningsDiagram::Private::~Private() {}
31 
32 
33 #define d d_func()
34 
35 
36 LeveyJenningsDiagram::LeveyJenningsDiagram( QWidget* parent, LeveyJenningsCoordinatePlane* plane )
37  : LineDiagram( new Private(), parent, plane )
38 {
39  init();
40 }
41 
42 void LeveyJenningsDiagram::init()
43 {
44  d->lotChangedPosition = Qt::AlignTop;
45  d->fluidicsPackChangedPosition = Qt::AlignBottom;
46  d->sensorChangedPosition = Qt::AlignBottom;
47 
48  d->scanLinePen = QPen( Qt::blue );
49  setPen( d->scanLinePen );
50 
51  d->expectedMeanValue = 0.0;
52  d->expectedStandardDeviation = 0.0;
53 
54  d->diagram = this;
55 
56  d->icons[ LotChanged ] = QString::fromLatin1( ":/KDE/kchart/LeveyJennings/karo_black.svg" );
57  d->icons[ SensorChanged ] = QString::fromLatin1( ":/KDE/kchart/LeveyJennings/karo_red.svg" );
58  d->icons[ FluidicsPackChanged ] = QString::fromLatin1( ":/KDE/kchart/LeveyJennings/karo_blue.svg" );
59  d->icons[ OkDataPoint ] = QString::fromLatin1( ":/KDE/kchart/LeveyJennings/circle_blue.svg" );
60  d->icons[ NotOkDataPoint ] = QString::fromLatin1( ":/KDE/kchart/LeveyJennings/circle_blue_red.svg" );
61 
63 }
64 
65 LeveyJenningsDiagram::~LeveyJenningsDiagram()
66 {
67 }
68 
70 {
71  LeveyJenningsDiagram* newDiagram = new LeveyJenningsDiagram( new Private( *d ) );
72  return newDiagram;
73 }
74 
76 {
77  if ( other == this ) return true;
78  if ( ! other ) {
79  return false;
80  }
81  /*
82  qDebug() <<"\n LineDiagram::compare():";
83  // compare own properties
84  qDebug() << (type() == other->type());
85  */
86  return // compare the base class
87  ( static_cast<const LineDiagram*>(this)->compare( other ) );
88 }
89 
91 {
92  if ( d->lotChangedPosition == pos )
93  return;
94 
95  d->lotChangedPosition = pos;
96  update();
97 }
98 
100 {
101  return d->lotChangedPosition;
102 }
103 
105 {
106  if ( d->fluidicsPackChangedPosition == pos )
107  return;
108 
109  d->fluidicsPackChangedPosition = pos;
110  update();
111 }
112 
114 {
115  return d->fluidicsPackChangedPosition;
116 }
117 
119 {
120  if ( d->sensorChangedPosition == pos )
121  return;
122 
123  d->sensorChangedPosition = pos;
124  update();
125 }
126 
128 {
129  return d->sensorChangedPosition;
130 }
131 
133 {
134  if ( d->fluidicsPackChanges == changes )
135  return;
136 
137  d->fluidicsPackChanges = changes;
138  update();
139 }
140 
142 {
143  return d->fluidicsPackChanges;
144 }
145 
147 {
148  if ( d->sensorChanges == changes )
149  return;
150 
151  d->sensorChanges = changes;
152  update();
153 }
154 
156 {
157  if ( d->scanLinePen == pen )
158  return;
159 
160  d->scanLinePen = pen;
161  update();
162 }
163 
165 {
166  return d->scanLinePen;
167 }
168 
169 QString LeveyJenningsDiagram::symbol( Symbol symbol ) const
170 {
171  return d->icons[ symbol ];
172 }
173 
174 void LeveyJenningsDiagram::setSymbol( Symbol symbol, const QString& filename )
175 {
176  if ( d->icons[ symbol ] == filename )
177  return;
178 
179  delete d->iconRenderer[ symbol ];
180  d->iconRenderer[ symbol ] = nullptr;
181 
182  d->icons[ symbol ] = filename;
183 
184  update();
185 }
186 
188 {
189  return d->sensorChanges;
190 }
191 
193 {
194  if ( d->expectedMeanValue == meanValue )
195  return;
196 
197  d->expectedMeanValue = meanValue;
198  d->setYAxisRange();
199  update();
200 }
201 
203 {
204  return d->expectedMeanValue;
205 }
206 
208 {
209  if ( d->expectedStandardDeviation == sd )
210  return;
211 
212  d->expectedStandardDeviation = sd;
213  d->setYAxisRange();
214  update();
215 }
216 
218 {
219  return d->expectedStandardDeviation;
220 }
221 
223 {
224  return d->calculatedMeanValue;
225 }
226 
228 {
229  return d->calculatedStandardDeviation;
230 }
231 
232 void LeveyJenningsDiagram::setModel( QAbstractItemModel* model )
233 {
234  if ( this->model() != nullptr )
235  {
237  this, SLOT(calculateMeanAndStandardDeviation()) );
238  disconnect( this->model(), SIGNAL(rowsInserted(QModelIndex,int,int)),
239  this, SLOT(calculateMeanAndStandardDeviation()) );
240  disconnect( this->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
241  this, SLOT(calculateMeanAndStandardDeviation()) );
242  disconnect( this->model(), SIGNAL(columnsInserted(QModelIndex,int,int)),
243  this, SLOT(calculateMeanAndStandardDeviation()) );
244  disconnect( this->model(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
245  this, SLOT(calculateMeanAndStandardDeviation()) );
246  disconnect( this->model(), SIGNAL(modelReset()),
247  this, SLOT(calculateMeanAndStandardDeviation()) );
248  disconnect( this->model(), SIGNAL(layoutChanged()),
249  this, SLOT(calculateMeanAndStandardDeviation()) );
250  }
251  LineDiagram::setModel( model );
252  if ( this->model() != nullptr )
253  {
254  connect( this->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
255  this, SLOT(calculateMeanAndStandardDeviation()) );
256  connect( this->model(), SIGNAL(rowsInserted(QModelIndex,int,int)),
257  this, SLOT(calculateMeanAndStandardDeviation()) );
258  connect( this->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
259  this, SLOT(calculateMeanAndStandardDeviation()) );
260  connect( this->model(), SIGNAL(columnsInserted(QModelIndex,int,int)),
261  this, SLOT(calculateMeanAndStandardDeviation()) );
262  connect( this->model(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
263  this, SLOT(calculateMeanAndStandardDeviation()) );
264  connect( this->model(), SIGNAL(modelReset()),
265  this, SLOT(calculateMeanAndStandardDeviation()) );
266  connect( this->model(), SIGNAL(layoutChanged()),
267  this, SLOT(calculateMeanAndStandardDeviation()) );
268 
269  calculateMeanAndStandardDeviation();
270  }
271 }
272 
273 // TODO: This is the 'easy' solution
274 // evaluate whether this is enough or we need some better one or even boost here
275 void LeveyJenningsDiagram::calculateMeanAndStandardDeviation() const
276 {
278  // first fetch all values
279  const QAbstractItemModel& m = *model();
280  const int rowCount = m.rowCount( rootIndex() );
281 
282  for ( int row = 0; row < rowCount; ++row )
283  {
284  const QVariant var = m.data( m.index( row, 1, rootIndex() ) );
285  if ( !var.isValid() )
286  continue;
287  const qreal value = var.toReal();
288  if ( ISNAN( value ) )
289  continue;
290  values << value;
291  }
292 
293  qreal sum = 0.0;
294  qreal sumSquares = 0.0;
295  for ( qreal value : qAsConst(values) )
296  {
297  sum += value;
298  sumSquares += value * value;
299  }
300 
301  const int N = values.count();
302 
303  d->calculatedMeanValue = sum / N;
304  d->calculatedStandardDeviation = sqrt( ( static_cast< qreal >( N ) * sumSquares - sum * sum ) / ( N * ( N - 1 ) ) );
305 }
306 
307 // calculates the largest QDate not greater than \a dt.
308 static QDate floorDay( const QDateTime& dt )
309 {
310  return dt.date();
311 }
312 
313 // calculates the smallest QDate not less than \a dt.
314 static QDate ceilDay( const QDateTime& dt )
315 {
316  QDate result = dt.date();
317 
318  if ( QDateTime( result, QTime() ) < dt )
319  result = result.addDays( 1 );
320 
321  return result;
322 }
323 
324 // calculates the largest QDateTime like xx:00 not greater than \a dt.
325 static QDateTime floorHour( const QDateTime& dt )
326 {
327  return QDateTime( dt.date(), QTime( dt.time().hour(), 0 ) );
328 }
329 
330 // calculates the smallest QDateTime like xx:00 not less than \a dt.
331 static QDateTime ceilHour( const QDateTime& dt )
332 {
333  QDateTime result( dt.date(), QTime( dt.time().hour(), 0 ) );
334 
335  if ( result < dt )
336  result = result.addSecs( 3600 );
337 
338  return result;
339 }
340 
342 {
343  const qreal yMin = d->expectedMeanValue - 4 * d->expectedStandardDeviation;
344  const qreal yMax = d->expectedMeanValue + 4 * d->expectedStandardDeviation;
345 
346  d->setYAxisRange();
347 
348  // rounded down/up to the prev/next midnight (at least that's the default)
350  const unsigned int minTime = range.first.toSecsSinceEpoch();
351  const unsigned int maxTime = range.second.toSecsSinceEpoch();
352 
353  const qreal xMin = minTime / static_cast< qreal >( 24 * 60 * 60 );
354  const qreal xMax = maxTime / static_cast< qreal >( 24 * 60 * 60 ) - xMin;
355 
356  const QPointF bottomLeft( QPointF( 0, yMin ) );
357  const QPointF topRight( QPointF( xMax, yMax ) );
358 
359  return QPair< QPointF, QPointF >( bottomLeft, topRight );
360 }
361 
363 {
364  if ( d->timeRange != QPair< QDateTime, QDateTime >() )
365  return d->timeRange;
366 
367  const QAbstractItemModel& m = *model();
368  const int rowCount = m.rowCount( rootIndex() );
369 
370  const QDateTime begin = m.data( m.index( 0, 3, rootIndex() ) ).toDateTime();
371  const QDateTime end = m.data( m.index( rowCount - 1, 3, rootIndex() ) ).toDateTime();
372 
373  if ( begin.secsTo( end ) > 86400 )
374  {
375  // if begin to end is more than 24h
376  // round down/up to the prev/next midnight
377  const QDate min = floorDay( begin );
378  const QDate max = ceilDay( end );
379  return QPair< QDateTime, QDateTime >( QDateTime( min, QTime() ), QDateTime( max, QTime() ) );
380  }
381  else if ( begin.secsTo( end ) > 3600 )
382  {
383  // more than 1h: rond down up to the prex/next hour
384  // if begin to end is more than 24h
385  const QDateTime min = floorHour( begin );
386  const QDateTime max = ceilHour( end );
387  return QPair< QDateTime, QDateTime >( min, max );
388  }
389  return QPair< QDateTime, QDateTime >( begin, end );
390 }
391 
393 {
394  if ( d->timeRange == timeRange )
395  return;
396 
397  d->timeRange = timeRange;
398  update();
399 }
400 
402 {
403  const unsigned int minTime = timeRange().first.toSecsSinceEpoch();
404 
405  for ( const QDateTime& dt : qAsConst(d->fluidicsPackChanges) )
406  {
407  const qreal xValue = ( dt.toSecsSinceEpoch() - minTime ) / static_cast< qreal >( 24 * 60 * 60 );
408  const QPointF point( xValue, 0.0 );
409  drawFluidicsPackChangedSymbol( ctx, point );
410  }
411 
412  for ( const QDateTime& dt : qAsConst(d->sensorChanges) )
413  {
414  const qreal xValue = ( dt.toSecsSinceEpoch() - minTime ) / static_cast< qreal >( 24 * 60 * 60 );
415  const QPointF point( xValue, 0.0 );
416  drawSensorChangedSymbol( ctx, point );
417  }
418 }
419 
421 {
422  d->reverseMapper.clear();
423 
424  // note: Not having any data model assigned is no bug
425  // but we can not draw a diagram then either.
426  if ( !checkInvariants( true ) ) return;
428 
429  QPainter* const painter = ctx->painter();
430  const PainterSaver p( painter );
431  if ( model()->rowCount( rootIndex() ) == 0 || model()->columnCount( rootIndex() ) < 4 )
432  return; // nothing to paint for us
433 
434  AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
435  ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( painter ) );
436 
437  const QAbstractItemModel& m = *model();
438  const int rowCount = m.rowCount( rootIndex() );
439 
440  const unsigned int minTime = timeRange().first.toSecsSinceEpoch();
441 
442  painter->setRenderHint( QPainter::Antialiasing, true );
443 
444  int prevLot = -1;
445  QPointF prevPoint;
446  bool hadMissingValue = false;
447 
448  for ( int row = 0; row < rowCount; ++row )
449  {
450  const QModelIndex lotIndex = m.index( row, 0, rootIndex() );
451  const QModelIndex valueIndex = m.index( row, 1, rootIndex() );
452  const QModelIndex okIndex = m.index( row, 2, rootIndex() );
453  const QModelIndex timeIndex = m.index( row, 3, rootIndex() );
454  const QModelIndex expectedMeanIndex = m.index( row, 4, rootIndex() );
455  const QModelIndex expectedSDIndex = m.index( row, 5, rootIndex() );
456 
457  painter->setPen( pen( lotIndex ) );
458 
459  QVariant vValue = m.data( valueIndex );
460  qreal value = vValue.toReal();
461  const int lot = m.data( lotIndex ).toInt();
462  const bool ok = m.data( okIndex ).toBool();
463  const QDateTime time = m.data( timeIndex ).toDateTime();
464  const qreal xValue = ( time.toSecsSinceEpoch() - minTime ) / static_cast< qreal >( 24 * 60 * 60 );
465 
466  QVariant vExpectedMean = m.data( expectedMeanIndex );
467  const qreal expectedMean = vExpectedMean.toReal();
468  QVariant vExpectedSD = m.data( expectedSDIndex );
469  const qreal expectedSD = vExpectedSD.toReal();
470 
471  QPointF point = ctx->coordinatePlane()->translate( QPointF( xValue, value ) );
472 
473  if ( vValue.isNull() )
474  {
475  hadMissingValue = true;
476  }
477  else
478  {
479  if ( !vExpectedMean.isNull() && !vExpectedSD.isNull() )
480  {
481  // this calculates the 'logical' value relative to the expected mean and SD of this point
482  value -= expectedMean;
483  value /= expectedSD;
484  value *= d->expectedStandardDeviation;
485  value += d->expectedMeanValue;
486  point = ctx->coordinatePlane()->translate( QPointF( xValue, value ) );
487  }
488 
489  if ( prevLot == lot )
490  {
491  const QPen pen = painter->pen();
492  QPen newPen = pen;
493 
494  if ( hadMissingValue )
495  {
496  newPen.setDashPattern( QVector< qreal >() << 4.0 << 4.0 );
497  }
498 
499  painter->setPen( newPen );
500  painter->drawLine( prevPoint, point );
501  painter->setPen( pen );
502  // d->reverseMapper.addLine( valueIndex.row(), valueIndex.column(), prevPoint, point );
503  }
504  else if ( row > 0 )
505  {
506  drawLotChangeSymbol( ctx, QPointF( xValue, value ) );
507  }
508 
509  if ( value <= d->expectedMeanValue + 4 * d->expectedStandardDeviation &&
510  value >= d->expectedMeanValue - 4 * d->expectedStandardDeviation )
511  {
512  const QPointF location( xValue, value );
513  drawDataPointSymbol( ctx, location, ok );
514  d->reverseMapper.addCircle( valueIndex.row(),
515  valueIndex.column(),
516  ctx->coordinatePlane()->translate( location ),
517  iconRect().size() );
518  }
519  prevLot = lot;
520  prevPoint = point;
521  hadMissingValue = false;
522  }
523 
524  const QModelIndex current = selectionModel()->currentIndex();
525  if ( selectionModel()->rowIntersectsSelection( lotIndex.row(), lotIndex.parent() ) || current.sibling( current.row(), 0 ) == lotIndex )
526  {
527  const QPen pen = ctx->painter()->pen();
528  painter->setPen( d->scanLinePen );
529  painter->drawLine( ctx->coordinatePlane()->translate( QPointF( xValue, d->expectedMeanValue - 4 *
530  d->expectedStandardDeviation ) ),
531  ctx->coordinatePlane()->translate( QPointF( xValue, d->expectedMeanValue + 4 *
532  d->expectedStandardDeviation ) ) );
533  painter->setPen( pen );
534  }
535  }
536 
537  drawChanges( ctx );
538 
539  ctx->setCoordinatePlane( plane );
540 }
541 
543 {
544  const Symbol type = ok ? OkDataPoint : NotOkDataPoint;
545 
546  QPainter* const painter = ctx->painter();
547  const PainterSaver ps( painter );
548  const QPointF transPos = ctx->coordinatePlane()->translate( pos ).toPoint();
549  painter->translate( transPos );
550 
551  painter->setClipping( false );
552  iconRenderer( type )->render( painter, iconRect() );
553 }
554 
556 {
557  const QPointF transPos = ctx->coordinatePlane()->translate(
558  QPointF( pos.x(), d->lotChangedPosition & Qt::AlignTop ? d->expectedMeanValue +
559  4 * d->expectedStandardDeviation
560  : d->expectedMeanValue -
561  4 * d->expectedStandardDeviation ) );
562 
563 
564  QPainter* const painter = ctx->painter();
565  const PainterSaver ps( painter );
566  painter->setClipping( false );
567  painter->translate( transPos );
568  iconRenderer( LotChanged )->render( painter, iconRect() );
569 }
570 
572 {
573  const QPointF transPos = ctx->coordinatePlane()->translate(
574  QPointF( pos.x(), d->sensorChangedPosition & Qt::AlignTop ? d->expectedMeanValue +
575  4 * d->expectedStandardDeviation
576  : d->expectedMeanValue -
577  4 * d->expectedStandardDeviation ) );
578 
579  QPainter* const painter = ctx->painter();
580  const PainterSaver ps( painter );
581  painter->setClipping( false );
582  painter->translate( transPos );
583  iconRenderer( SensorChanged )->render( painter, iconRect() );
584 }
585 
587 {
588  const QPointF transPos = ctx->coordinatePlane()->translate(
589  QPointF( pos.x(), d->fluidicsPackChangedPosition & Qt::AlignTop ? d->expectedMeanValue +
590  4 * d->expectedStandardDeviation
591  : d->expectedMeanValue -
592  4 * d->expectedStandardDeviation ) );
593 
594  QPainter* const painter = ctx->painter();
595  const PainterSaver ps( painter );
596  painter->setClipping( false );
597  painter->translate( transPos );
598  iconRenderer( FluidicsPackChanged )->render( painter, iconRect() );
599 }
600 
602 {
603  const Measure m( 12.5, KChartEnums::MeasureCalculationModeAuto, KChartEnums::MeasureOrientationAuto );
604  TextAttributes test;
605  test.setFontSize( m );
606  const QFontMetrics fm( test.calculatedFont( coordinatePlane()->parent(), KChartEnums::MeasureOrientationAuto ) );
607  const qreal height = fm.height() / 1.2;
608  return QRectF( -height / 2.0, -height / 2.0, height, height );
609 }
610 
612 {
613  if ( d->iconRenderer[ symbol ] == nullptr )
614  d->iconRenderer[ symbol ] = new QSvgRenderer( d->icons[ symbol ], this );
615 
616  return d->iconRenderer[ symbol ];
617 }
qreal toReal(bool *ok) const const
virtual void rowsInserted(const QModelIndex &parent, int start, int end)
QVector< QDateTime > sensorChanges() const
Returns the list of all sensor changes.
bool isNull() const const
AlignTop
void paint(PaintContext *paintContext) override
\reimpl
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector< int > &roles=QVector< int >()) override
\reimpl
virtual void drawSensorChangedSymbol(PaintContext *paintContext, const QPointF &pos)
Draws a sensor changed symbol for the data point at pos.
void setPen(const QColor &color)
bool isValid() const const
QVector< QDateTime > fluidicsPackChanges() const
Returns the list of all fluidics pack changes.
void render(QPainter *painter)
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
virtual int rowCount(const QModelIndex &parent) const const=0
virtual void drawLotChangeSymbol(PaintContext *paintContext, const QPointF &pos)
Draws a lot changed symbol for the data point at pos.
QModelIndex sibling(int row, int column) const const
virtual QVariant data(const QModelIndex &index, int role) const const=0
float calculatedStandardDeviation() const
Returns the calculated standard deviation over all QC values.
QAbstractItemModel * model() const const
int column() const const
QTime time() const const
Class only listed here to document inheritance of some KChart classes.
QPair< QDateTime, QDateTime > timeRange() const
Returns the timerange of the diagram's data.
QItemSelectionModel * selectionModel() const const
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
void setSelectionMode(QAbstractItemView::SelectionMode mode)
float expectedMeanValue() const
Returns the expected mean values over all QC values.
const QPair< QPointF, QPointF > dataBoundaries() const
Return the bottom left and top right data point, that the diagram will display (unless the grid adjus...
Stores information about painting diagrams.
const QPen & pen() const const
Levey Jennings coordinate plane This is actually nothing real more than a plain cartesian coordinate ...
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Qt::Alignment fluidicsPackChangedSymbolPosition() const
Returns the position of the fluidics pack changed symbol.
QString symbol(Symbol symbol) const
Returns the SVG file name usef for symbol.
Qt::Alignment lotChangedSymbolPosition() const
Returns the position of the lot change symbol.
Qt::Alignment sensorChangedSymbolPosition() const
Returns the position of the sensor changed symbol.
void drawChanges(PaintContext *paintContext)
Draws the fluidics pack and sensor changed symbols.
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
float calculatedMeanValue() const
Returns the calculated mean values over all QC values.
void setDashPattern(const QVector< qreal > &pattern)
void setLotChangedSymbolPosition(Qt::Alignment pos)
Sets the position of the lot change symbol to pos.
LeveyDiagram defines a Levey Jennings chart.
virtual const QPointF translate(const QPointF &diagramPoint) const =0
Translate the given point in value space coordinates to a position in pixel space.
void setExpectedStandardDeviation(float sd)
Sets the expected standard deviaction over all QC values to sd.
int toInt(bool *ok) const const
void setScanLinePen(const QPen &pen)
Sets the pen used for drawing the scan line to pen.
void init(KXmlGuiWindow *window, KgDifficulty *difficulty=nullptr)
QPen scanLinePen() const
Returns the pen being used for drawing the scan line.
QDate addDays(qint64 ndays) const const
QModelIndex rootIndex() const const
const QPair< QPointF, QPointF > calculateDataBoundaries() const override
\reimpl
LineDiagram * clone() const override
Creates an exact copy of this diagram.
int hour() const const
bool toBool() const const
void setTimeRange(const QPair< QDateTime, QDateTime > &timeRange)
Sets the timeRange visible on the x axis.
void setFluidicsPackChangedSymbolPosition(Qt::Alignment pos)
Sets the position of the fluidics pack changed symbol to pos.
int row() const const
Measure is used to specify relative and absolute sizes in KChart, e.g. font sizes.
Definition: KChartMeasure.h:37
void setPen(const QModelIndex &index, const QPen &pen)
Set the pen to be used, for painting the datapoint at the given index.
bool compare(const LeveyJenningsDiagram *other) const
Returns true if both diagrams have the same settings.
qint64 toSecsSinceEpoch() const const
static bool isBoundariesValid(const QRectF &r)
Checks whether both coordinates of r are valid according to isValueValid.
QDateTime toDateTime() const const
void setSymbol(Symbol symbol, const QString &filename)
Sets the symbol being used for symbol to a SVG file filename.
QString fromLatin1(const char *str, int size)
void setFluidicsPackChanges(const QVector< QDateTime > &changes)
Sets the date/time of all fluidics pack changes to changes.
QDate date() const const
void setSensorChangedSymbolPosition(Qt::Alignment pos)
Sets the position of the sensor changed symbol to pos.
void drawLine(const QLineF &line)
QPoint toPoint() const const
void translate(const QPointF &offset)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
virtual void drawFluidicsPackChangedSymbol(PaintContext *paintContext, const QPointF &pos)
Draws a fluidics pack changed symbol for the data point at pos.
LineDiagram defines a common line diagram.
void setExpectedMeanValue(float meanValue)
Sets the expected mean value over all QC values to meanValue.
float expectedStandardDeviation() const
Returns the expected standard deviation over all QC values.
virtual QRectF iconRect() const
Returns the rectangle being used for drawing the icons.
QModelIndex parent() const const
QPen pen() const
Retrieve the pen to be used for painting datapoints globally.
QModelIndex currentIndex() const const
void setRenderHint(QPainter::RenderHint hint, bool on)
A set of text attributes.
int height() const const
void layoutChanged(KChart::AbstractDiagram *)
Diagrams are supposed to emit this signal, when the layout of one of their element changes.
QVector< V > values(const QMultiHash< K, V > &c)
QObject * parent() const const
void setClipping(bool enable)
void setSensorChanges(const QVector< QDateTime > &changes)
Sets the date/time of all sensor changes to changes.
QSvgRenderer * iconRenderer(Symbol symbol)
Returns the SVG icon renderer for symbol.
virtual void drawDataPointSymbol(PaintContext *paintContext, const QPointF &pos, bool ok)
Draws a data point symbol for the data point at pos.
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.