Engauge Digitizer  2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Curve.cpp
Go to the documentation of this file.
1 /******************************************************************************************************
2  * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3  * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4  * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5  ******************************************************************************************************/
6 
7 #include "Curve.h"
8 #include "CurvesGraphs.h"
9 #include "CurveStyle.h"
10 #include "DocumentSerialize.h"
11 #include "EngaugeAssert.h"
12 #include "Logger.h"
13 #include "MigrateToVersion6.h"
14 #include "Point.h"
15 #include "PointComparator.h"
16 #include <QDataStream>
17 #include <QDebug>
18 #include <qmath.h>
19 #include <QMultiMap>
20 #include <QTextStream>
21 #include <QXmlStreamReader>
22 #include <QXmlStreamWriter>
23 #include "Transformation.h"
24 #include "Xml.h"
25 
26 const QString AXIS_CURVE_NAME ("Axes");
27 const QString DEFAULT_GRAPH_CURVE_NAME ("Curve1");
28 const QString DUMMY_CURVE_NAME ("dummy");
29 const QString SCALE_CURVE_NAME ("Scale"); // Used for pre-version 6 input files
30 const QString TAB_DELIMITER ("\t");
31 
32 // This has to be a multimap instead of a map since some users may mistakenly allow multiple points with the
33 // same x coordinate in their functions even though that should not happen
34 typedef QMultiMap<double, QString> XOrThetaToPointIdentifier;
35 
36 Curve::Curve(const QString &curveName,
37  const ColorFilterSettings &colorFilterSettings,
38  const CurveStyle &curveStyle) :
39  m_curveName (curveName),
40  m_colorFilterSettings (colorFilterSettings),
41  m_curveStyle (curveStyle)
42 {
43 }
44 
45 Curve::Curve (const Curve &curve) :
46  m_curveName (curve.curveName ()),
47  m_points (curve.points ()),
48  m_colorFilterSettings (curve.colorFilterSettings ()),
49  m_curveStyle (curve.curveStyle ())
50 {
51 }
52 
53 Curve::Curve (QDataStream &str)
54 {
55  const int CONVERT_ENUM_TO_RADIUS = 6;
56  MigrateToVersion6 migrate;
57 
58  qint32 int32, xScreen, yScreen;
59  double xGraph, yGraph;
60 
61  str >> m_curveName;
62 
63  // Scale bar points are handled as if they are axis points
64  if (m_curveName == SCALE_CURVE_NAME) {
65  m_curveName = AXIS_CURVE_NAME;
66  }
67 
68  str >> int32;
69  m_curveStyle.setPointShape(migrate.pointShape (int32));
70  str >> int32;
71  m_curveStyle.setPointRadius(int32 + CONVERT_ENUM_TO_RADIUS);
72  str >> int32;
73  m_curveStyle.setPointLineWidth (int32);
74  str >> int32;
75  m_curveStyle.setPointColor(migrate.colorPalette (int32));
76  str >> int32; // Point interior color
77  str >> int32;
78  m_curveStyle.setLineWidth(int32);
79  str >> int32;
80  if (m_curveName == AXIS_CURVE_NAME) {
81  m_curveStyle.setLineColor(migrate.colorPalette (int32));
82  } else {
84  }
85  str >> int32;
86  m_curveStyle.setLineConnectAs(migrate.curveConnectAs (int32));
87 
88  str >> int32;
89  int count = int32;
90  int ordinal = 0;
91  for (int i = 0; i < count; i++) {
92 
93  str >> xScreen;
94  str >> yScreen;
95  str >> xGraph;
96  str >> yGraph;
97  if (m_curveName == AXIS_CURVE_NAME) {
98 
99  // Axis point, with graph coordinates set by user and managed here
100  Point point (m_curveName,
101  QPointF (xScreen, yScreen),
102  QPointF (xGraph, yGraph),
103  ordinal++,
104  false);
105 
106  addPoint(point);
107  } else {
108 
109  // Curve point, with graph coordinates managed elsewhere
110  Point point (m_curveName,
111  QPointF (xScreen, yScreen));
112  point.setOrdinal (ordinal++);
113 
114  addPoint(point);
115  }
116  }
117 }
118 
119 Curve::Curve (QXmlStreamReader &reader)
120 {
121  loadXml(reader);
122 }
123 
125 {
126  m_curveName = curve.curveName ();
127  m_points = curve.points ();
128  m_colorFilterSettings = curve.colorFilterSettings ();
129  m_curveStyle = curve.curveStyle ();
130 
131  return *this;
132 }
133 
134 void Curve::addPoint (const Point &point)
135 {
136  m_points.push_back (point);
137 }
138 
140 {
141  return m_colorFilterSettings;
142 }
143 
144 QString Curve::curveName () const
145 {
146  return m_curveName;
147 }
148 
150 {
151  return m_curveStyle;
152 }
153 
154 void Curve::editPointAxis (const QPointF &posGraph,
155  const QString &identifier)
156 {
157  // Search for the point with matching identifier
158  QList<Point>::iterator itr;
159  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
160 
161  Point &point = *itr;
162  if (point.identifier () == identifier) {
163 
164  point.setPosGraph (posGraph);
165  break;
166 
167  }
168  }
169 }
170 
171 void Curve::editPointGraph (bool isX,
172  bool isY,
173  double x,
174  double y,
175  const QStringList &identifiers,
176  const Transformation &transformation)
177 {
178  LOG4CPP_INFO_S ((*mainCat)) << "Curve::editPointGraph"
179  << " identifiers=" << identifiers.join(" ").toLatin1().data();
180 
181  if (transformation.transformIsDefined()) {
182 
183  // Search for the point with matching identifier
184  QList<Point>::iterator itr;
185  for (itr = m_points.begin(); itr != m_points.end(); itr++) {
186 
187  Point &point = *itr;
188 
189  if (identifiers.contains (point.identifier ())) {
190 
191  // Although one or more graph coordinates are specified, it is the screen coordinates that must be
192  // moved. This is because only the screen coordinates of the graph points are tracked (not the graph coordinates).
193  // So we compute posScreen and call Point::setPosScreen instead of Point::setPosGraph
194 
195  // Get original graph coordinates
196  QPointF posScreen = point.posScreen ();
197  QPointF posGraph;
198  transformation.transformScreenToRawGraph (posScreen,
199  posGraph);
200 
201  // Override one or both coordinates
202  if (isX) {
203  posGraph.setX (x);
204  }
205 
206  if (isY) {
207  posGraph.setY (y);
208  }
209 
210  // Set the screen coordinates
211  transformation.transformRawGraphToScreen(posGraph,
212  posScreen);
213 
214  point.setPosScreen (posScreen);
215  }
216  }
217  }
218 }
219 
220 void Curve::exportToClipboard (const QHash<QString, bool> &selectedHash,
221  const Transformation &transformation,
222  QTextStream &strCsv,
223  QTextStream &strHtml,
224  CurvesGraphs &curvesGraphs) const
225 {
226  LOG4CPP_INFO_S ((*mainCat)) << "Curve::exportToClipboard"
227  << " hashCount=" << selectedHash.count();
228 
229  // This method assumes Copy is only allowed when Transformation is valid
230 
231  bool isFirst = true;
232  QList<Point>::const_iterator itr;
233  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
234 
235  const Point &point = *itr;
236  if (selectedHash.contains (point.identifier ())) {
237 
238  if (isFirst) {
239 
240  // Insert headers to identify the points that follow
241  isFirst = false;
242  strCsv << "X" << TAB_DELIMITER << m_curveName << "\n";
243  strHtml << "<table>\n"
244  << "<tr><th>X</th><th>" << m_curveName << "</th></tr>\n";
245  }
246 
247  // Default curve style
248  CurveStyle curveStyleDefault;
249  curveStyleDefault.setLineStyle(LineStyle::defaultAxesCurve());
250  curveStyleDefault.setPointStyle(PointStyle::defaultGraphCurve (curvesGraphs.numCurves ()));
251 
252  // Check if this curve already exists from a previously exported point
253  if (curvesGraphs.curveForCurveName (m_curveName) == nullptr) {
254  Curve curve(m_curveName,
256  curveStyleDefault);
257  curvesGraphs.addGraphCurveAtEnd(curve);
258  }
259 
260  // Start with screen coordinates
261  QPointF pos = point.posScreen();
262  if (transformation.transformIsDefined()) {
263 
264  // Replace with graph coordinates which are almost always more useful
265  QPointF posGraph;
266  transformation.transformScreenToRawGraph(pos,
267  posGraph);
268  pos = posGraph;
269  }
270 
271  // Add point to text going to clipboard
272  strCsv << pos.x() << TAB_DELIMITER << pos.y() << "\n";
273  strHtml << "<tr><td>" << pos.x() << "</td><td>" << pos.y() << "</td></tr>\n";
274 
275  // Add point to list for undo/redo
276  curvesGraphs.curveForCurveName (m_curveName)->addPoint (point);
277  }
278  }
279 
280  if (!isFirst) {
281  strHtml << "</table>\n";
282  }
283 }
284 
285 bool Curve::isXOnly(const QString &pointIdentifier) const
286 {
287  // Search for point with matching identifier
288  Points::const_iterator itr;
289  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
290  const Point &point = *itr;
291  if (pointIdentifier == point.identifier ()) {
292  return point.isXOnly();
293  }
294  }
295 
296  ENGAUGE_ASSERT (false);
297 
298  return false;
299 }
300 
301 void Curve::iterateThroughCurvePoints (const Functor2wRet<const QString &, const Point&, CallbackSearchReturn> &ftorWithCallback) const
302 {
303  QList<Point>::const_iterator itr;
304  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
305 
306  const Point &point = *itr;
307 
308  CallbackSearchReturn rtn = ftorWithCallback (m_curveName, point);
309 
311  break;
312  }
313  }
314 }
315 
316 void Curve::iterateThroughCurveSegments (const Functor2wRet<const Point&, const Point&, CallbackSearchReturn> &ftorWithCallback) const
317 {
318  // Loop through Points. They are assumed to be already sorted by their ordinals, but we do NOT
319  // check the ordinal ordering since this could be called before, or while, the ordinal sorting is done
320  QList<Point>::const_iterator itr;
321  const Point *pointBefore = nullptr;
322  for (itr = m_points.begin(); itr != m_points.end(); itr++) {
323 
324  const Point &point = *itr;
325 
326  if (pointBefore != nullptr) {
327 
328  CallbackSearchReturn rtn = ftorWithCallback (*pointBefore,
329  point);
330 
332  break;
333  }
334 
335  }
336  pointBefore = &point;
337  }
338 }
339 
340 void Curve::loadCurvePoints(QXmlStreamReader &reader)
341 {
342  LOG4CPP_INFO_S ((*mainCat)) << "Curve::loadCurvePoints";
343 
344  bool success = true;
345 
346  while ((reader.tokenType() != QXmlStreamReader::EndElement) ||
347  (reader.name() != DOCUMENT_SERIALIZE_CURVE_POINTS)) {
348 
349  QXmlStreamReader::TokenType tokenType = loadNextFromReader(reader);
350 
351  if (reader.atEnd()) {
352  success = false;
353  break;
354  }
355 
356  if (tokenType == QXmlStreamReader::StartElement) {
357 
358  if (reader.name () == DOCUMENT_SERIALIZE_POINT) {
359 
360  Point point (reader);
361  m_points.push_back (point);
362  }
363  }
364  }
365 
366  if (!success) {
367  reader.raiseError(QObject::tr ("Cannot read curve data"));
368  }
369 }
370 
371 void Curve::loadXml(QXmlStreamReader &reader)
372 {
373  LOG4CPP_INFO_S ((*mainCat)) << "Curve::loadXml";
374 
375  bool success = true;
376 
377  QXmlStreamAttributes attributes = reader.attributes();
378 
379  if (attributes.hasAttribute (DOCUMENT_SERIALIZE_CURVE_NAME)) {
380 
381  setCurveName (attributes.value (DOCUMENT_SERIALIZE_CURVE_NAME).toString());
382 
383  // Read until end of this subtree
384  while ((reader.tokenType() != QXmlStreamReader::EndElement) ||
385  (reader.name() != DOCUMENT_SERIALIZE_CURVE)){
386 
387  QXmlStreamReader::TokenType tokenType = loadNextFromReader(reader);
388 
389  if (reader.atEnd()) {
390  success = false;
391  break;
392  }
393 
394  if (tokenType == QXmlStreamReader::StartElement) {
395 
396  if (reader.name() == DOCUMENT_SERIALIZE_COLOR_FILTER) {
397  m_colorFilterSettings.loadXml(reader);
398  } else if (reader.name() == DOCUMENT_SERIALIZE_CURVE_POINTS) {
399  loadCurvePoints(reader);
400  } else if (reader.name() == DOCUMENT_SERIALIZE_CURVE_STYLE) {
401  m_curveStyle.loadXml(reader);
402  } else {
403  success = false;
404  break;
405  }
406  }
407 
408  if (reader.hasError()) {
409  // No need to set success flag to indicate failure, which raises the error, since the error was already raised. Just
410  // need to exit the loop immediately
411  break;
412  }
413  }
414  } else {
415  success = false;
416  }
417 
418  if (!success) {
419  reader.raiseError (QObject::tr ("Cannot read curve data"));
420  }
421 }
422 
423 void Curve::movePoint (const QString &pointIdentifier,
424  const QPointF &deltaScreen)
425 {
426  Point *point = pointForPointIdentifier (pointIdentifier);
427 
428  QPointF posScreen = deltaScreen + point->posScreen ();
429  point->setPosScreen (posScreen);
430 }
431 
432 int Curve::numPoints () const
433 {
434  return m_points.count ();
435 }
436 
437 Point *Curve::pointForPointIdentifier (const QString pointIdentifier)
438 {
439  Points::iterator itr;
440  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
441  Point &point = *itr;
442  if (pointIdentifier == point.identifier ()) {
443  return &point;
444  }
445  }
446 
447  ENGAUGE_ASSERT (false);
448  return nullptr;
449 }
450 
451 const Points Curve::points () const
452 {
453  return m_points;
454 }
455 
456 QPointF Curve::positionGraph (const QString &pointIdentifier) const
457 {
458  QPointF posGraph;
459 
460  // Search for point with matching identifier
461  Points::const_iterator itr;
462  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
463  const Point &point = *itr;
464  if (pointIdentifier == point.identifier ()) {
465  posGraph = point.posGraph ();
466  break;
467  }
468  }
469 
470  return posGraph;
471 }
472 
473 QPointF Curve::positionScreen (const QString &pointIdentifier) const
474 {
475  QPointF posScreen;
476 
477  // Search for point with matching identifier
478  Points::const_iterator itr;
479  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
480  const Point &point = *itr;
481  if (pointIdentifier == point.identifier ()) {
482  posScreen = point.posScreen ();
483  break;
484  }
485  }
486 
487  return posScreen;
488 }
489 
490 void Curve::printStream (QString indentation,
491  QTextStream &str) const
492 {
493  str << indentation << "Curve=" << m_curveName << "\n";
494 
495  indentation += INDENTATION_DELTA;
496 
497  Points::const_iterator itr;
498  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
499  const Point &point = *itr;
500  point.printStream (indentation,
501  str);
502  }
503 
504  m_colorFilterSettings.printStream (indentation,
505  str);
506  m_curveStyle.printStream (indentation,
507  str);
508 }
509 
510 void Curve::removePoint (const QString &identifier)
511 {
512  // Search for point with matching identifier
513  Points::iterator itr;
514  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
515  Point point = *itr;
516  if (point.identifier () == identifier) {
517  m_points.erase (itr);
518  break;
519  }
520  }
521 }
522 
523 void Curve::saveXml(QXmlStreamWriter &writer) const
524 {
525  LOG4CPP_INFO_S ((*mainCat)) << "Curve::saveXml";
526 
527  writer.writeStartElement(DOCUMENT_SERIALIZE_CURVE);
528  writer.writeAttribute(DOCUMENT_SERIALIZE_CURVE_NAME, m_curveName);
529  m_colorFilterSettings.saveXml (writer,
530  m_curveName);
531  m_curveStyle.saveXml (writer,
532  m_curveName);
533 
534  // Loop through points
535  writer.writeStartElement(DOCUMENT_SERIALIZE_CURVE_POINTS);
536  Points::const_iterator itr;
537  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
538  const Point &point = *itr;
539  point.saveXml (writer);
540  }
541  writer.writeEndElement();
542 
543  writer.writeEndElement();
544 }
545 
546 void Curve::setColorFilterSettings (const ColorFilterSettings &colorFilterSettings)
547 {
548  m_colorFilterSettings = colorFilterSettings;
549 }
550 
551 void Curve::setCurveName (const QString &curveName)
552 {
553  m_curveName = curveName;
554 
555  // Pass to member objects
556  QList<Point>::iterator itr;
557  for (itr = m_points.begin(); itr != m_points.end(); itr++) {
558  Point &point = *itr;
559  point.setCurveName (curveName);
560  }
561 }
562 
563 void Curve::setCurveStyle (const CurveStyle &curveStyle)
564 {
565  m_curveStyle = curveStyle;
566 }
567 
568 void Curve::updatePointOrdinals (const Transformation &transformation)
569 {
570  CurveConnectAs curveConnectAs = m_curveStyle.lineStyle().curveConnectAs();
571 
572  LOG4CPP_INFO_S ((*mainCat)) << "Curve::updatePointOrdinals"
573  << " curve=" << m_curveName.toLatin1().data()
574  << " connectAs=" << curveConnectAsToString(curveConnectAs).toLatin1().data();
575 
576  // Make sure ordinals are properly ordered. Sorting is done afterward
577 
578  if (curveConnectAs == CONNECT_AS_FUNCTION_SMOOTH ||
579  curveConnectAs == CONNECT_AS_FUNCTION_STRAIGHT) {
580 
581  updatePointOrdinalsFunctions (transformation);
582 
583  } else if (curveConnectAs == CONNECT_AS_RELATION_SMOOTH ||
584  curveConnectAs == CONNECT_AS_RELATION_STRAIGHT) {
585 
586  updatePointOrdinalsRelations ();
587 
588  } else {
589 
590  LOG4CPP_ERROR_S ((*mainCat)) << "Curve::updatePointOrdinals";
591  ENGAUGE_ASSERT (false);
592 
593  }
594 
595  qSort (m_points.begin(),
596  m_points.end(),
597  PointComparator());
598 }
599 
600 void Curve::updatePointOrdinalsFunctions (const Transformation &transformation)
601 {
602  CurveConnectAs curveConnectAs = m_curveStyle.lineStyle().curveConnectAs();
603 
604  LOG4CPP_INFO_S ((*mainCat)) << "Curve::updatePointOrdinalsFunctions"
605  << " curve=" << m_curveName.toLatin1().data()
606  << " connectAs=" << curveConnectAsToString(curveConnectAs).toLatin1().data();
607 
608  // Get a map of x/theta values as keys with point identifiers as the values. This has to be a multimap since
609  // some users will have two (or maybe more) points with the same x coordinate, even though true functions should
610  // never have that happen
611  XOrThetaToPointIdentifier xOrThetaToPointIdentifier;
612  Points::iterator itr;
613  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
614  Point &point = *itr;
615 
616  QPointF posGraph;
617  if (transformation.transformIsDefined()) {
618 
619  // Transformation is available so use it
620  transformation.transformScreenToRawGraph (point.posScreen (),
621  posGraph);
622  } else {
623 
624  // Transformation is not available so we just use the screen coordinates. Effectively, the
625  // transformation is the identity matrix
626  posGraph= point.posScreen();
627  }
628 
629  xOrThetaToPointIdentifier.insert (posGraph.x(),
630  point.identifier());
631  }
632 
633  // Every point in m_points must be in the map. Failure to perform this check will probably result in the assert
634  // below getting triggered
635  ENGAUGE_ASSERT (xOrThetaToPointIdentifier.count () == m_points.count ());
636 
637  // Since m_points is a list (and therefore does not provide direct access to elements), we build a temporary map of
638  // point identifier to ordinal, by looping through the sorted x/theta values. Since QMap is used, the x/theta keys are sorted
639  QMap<QString, double> pointIdentifierToOrdinal;
640  int ordinal = 0;
641  XOrThetaToPointIdentifier::const_iterator itrX;
642  for (itrX = xOrThetaToPointIdentifier.begin(); itrX != xOrThetaToPointIdentifier.end(); itrX++) {
643 
644  QString pointIdentifier = itrX.value();
645  pointIdentifierToOrdinal [pointIdentifier] = ordinal++;
646  }
647 
648  // Override the old ordinal values
649  for (itr = m_points.begin(); itr != m_points.end(); itr++) {
650  Point &point = *itr;
651 
652  // Make sure point is in the map list. If this test is skipped then the square bracket operator
653  // will insert an entry with a zero ordinal, and the presence of multiple points with the same zero ordinal will
654  // cause problems downstream
655  ENGAUGE_ASSERT (pointIdentifierToOrdinal.contains (point.identifier()));
656 
657  // Point is to be included since it is in the map list.
658  int ordinalNew = qFloor (pointIdentifierToOrdinal [point.identifier()]);
659  point.setOrdinal (ordinalNew);
660  }
661 }
662 
663 void Curve::updatePointOrdinalsRelations ()
664 {
665  CurveConnectAs curveConnectAs = m_curveStyle.lineStyle().curveConnectAs();
666 
667  LOG4CPP_INFO_S ((*mainCat)) << "Curve::updatePointOrdinalsRelations"
668  << " curve=" << m_curveName.toLatin1().data()
669  << " connectAs=" << curveConnectAsToString(curveConnectAs).toLatin1().data();
670 
671  // Keep the ordinal numbering, but make sure the ordinals are evenly spaced
672  Points::iterator itr;
673  int ordinal = 0;
674  for (itr = m_points.begin(); itr != m_points.end(); itr++) {
675  Point &point = *itr;
676  point.setOrdinal (ordinal++);
677  }
678 }
void transformScreenToRawGraph(const QPointF &coordScreen, QPointF &coordGraph) const
Transform from cartesian pixel screen coordinates to cartesian/polar graph coordinates.
void removePoint(const QString &identifier)
Perform the opposite of addPointAtEnd.
Definition: Curve.cpp:510
QPointF positionScreen(const QString &pointIdentifier) const
Return the position, in screen coordinates, of the specified Point.
Definition: Curve.cpp:473
QPointF posGraph(ApplyHasCheck applyHasCheck=KEEP_HAS_CHECK) const
Accessor for graph position. Skip check if copying one instance to another.
Definition: Point.cpp:395
Comparator for sorting Point class.
void saveXml(QXmlStreamWriter &writer, const QString &curveName) const
Serialize to xml.
Definition: CurveStyle.cpp:93
Color filter parameters for one curve. For a class, this is handled the same as LineStyle and PointSt...
QXmlStreamReader::TokenType loadNextFromReader(QXmlStreamReader &reader)
Load next token from xml reader.
Definition: Xml.cpp:14
const QString DOCUMENT_SERIALIZE_CURVE_POINTS
void exportToClipboard(const QHash< QString, bool > &selectedHash, const Transformation &transformation, QTextStream &strCsv, QTextStream &strHtml, CurvesGraphs &curvesGraphs) const
Export points in this Curve found in the specified point list.
Definition: Curve.cpp:220
const Points points() const
Return a shallow copy of the Points.
Definition: Curve.cpp:451
void setCurveStyle(const CurveStyle &curveStyle)
Set curve style.
Definition: Curve.cpp:563
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
Definition: CurveStyle.cpp:80
const QString INDENTATION_DELTA
void setColorFilterSettings(const ColorFilterSettings &colorFilterSettings)
Set color filter.
Definition: Curve.cpp:546
const QString DOCUMENT_SERIALIZE_POINT
void saveXml(QXmlStreamWriter &writer) const
Serialize to stream.
Definition: Point.cpp:432
Curve * curveForCurveName(const QString &curveName)
Return the axis or graph curve for the specified curve name.
int numCurves() const
Current number of graphs curves.
int numPoints() const
Number of points.
Definition: Curve.cpp:432
void updatePointOrdinals(const Transformation &transformation)
See CurveGraphs::updatePointOrdinals.
Definition: Curve.cpp:568
LineStyle lineStyle() const
Get method for LineStyle.
Definition: CurveStyle.cpp:26
void setPointShape(PointShape shape)
Set method for curve point shape in specified curve.
Definition: CurveStyle.cpp:140
void editPointAxis(const QPointF &posGraph, const QString &identifier)
Edit the graph coordinates of an axis point. This method does not apply to a graph point...
Definition: Curve.cpp:154
bool isXOnly(const QString &pointIdentifier) const
Determine if specified point has just x coordinate. Otherwise has just y coordinate, or both x and y coordinates.
Definition: Curve.cpp:285
#define LOG4CPP_INFO_S(logger)
Definition: convenience.h:18
Class that represents one digitized point. The screen-to-graph coordinate transformation is always ex...
Definition: Point.h:25
static LineStyle defaultAxesCurve()
Initial default for axes curve.
Definition: LineStyle.cpp:68
void addGraphCurveAtEnd(const Curve &curve)
Append new graph Curve to end of Curve list.
QPointF posScreen() const
Accessor for screen position.
Definition: Point.cpp:404
void setLineConnectAs(CurveConnectAs curveConnectAs)
Set method for connect as method for lines in specified curve.
Definition: CurveStyle.cpp:110
QPointF positionGraph(const QString &pointIdentifier) const
Return the position, in graph coordinates, of the specified Point.
Definition: Curve.cpp:456
void setLineStyle(const LineStyle &lineStyle)
Set method for LineStyle.
Definition: CurveStyle.cpp:115
Curve(const QString &curveName, const ColorFilterSettings &colorFilterSettings, const CurveStyle &curveStyle)
Constructor from scratch.
Definition: Curve.cpp:36
const QString DOCUMENT_SERIALIZE_CURVE
void setPosGraph(const QPointF &posGraph)
Set method for position in graph coordinates.
Definition: Point.cpp:496
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
Definition: Curve.cpp:490
ColorPalette colorPalette(int preVersion6) const
Color from color palette.
Curve & operator=(const Curve &curve)
Assignment constructor.
Definition: Curve.cpp:124
CallbackSearchReturn
Return values for search callback methods.
QString identifier() const
Unique identifier for a specific Point.
Definition: Point.cpp:268
#define LOG4CPP_ERROR_S(logger)
Definition: convenience.h:12
Converts old (=pre version 6) enums to new (=version 6) enums, for reading of old document files...
PointShape pointShape(int preVersion6) const
Point shape.
void saveXml(QXmlStreamWriter &writer, const QString &curveName) const
Save curve filter to stream.
void movePoint(const QString &pointIdentifier, const QPointF &deltaScreen)
Translate the position of a point by the specified distance vector.
Definition: Curve.cpp:423
void setPointRadius(int radius)
Set method for curve point radius.
Definition: CurveStyle.cpp:135
void setPointLineWidth(int width)
Set method for curve point perimeter line width.
Definition: CurveStyle.cpp:130
static ColorFilterSettings defaultFilter()
Initial default for any Curve.
Affine transformation between screen and graph coordinates, based on digitized axis points...
const QString DOCUMENT_SERIALIZE_COLOR_FILTER
QString loadXml(QXmlStreamReader &reader)
Load from serialized xml. Returns the curve name.
Definition: CurveStyle.cpp:31
Container for all graph curves. The axes point curve is external to this class.
Definition: CurvesGraphs.h:24
bool isXOnly() const
In DOCUMENT_AXES_POINTS_REQUIRED_4 modes, this is true/false if y/x coordinate is undefined...
Definition: Point.cpp:286
const QString DUMMY_CURVE_NAME
void iterateThroughCurvePoints(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback) const
Apply functor to Points on Curve.
Definition: Curve.cpp:301
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
Definition: Point.cpp:409
void setCurveName(const QString &curveName)
Change the curve name.
Definition: Curve.cpp:551
const QString DOCUMENT_SERIALIZE_CURVE_STYLE
Container for LineStyle and PointStyle for one Curve.
Definition: CurveStyle.h:18
CurveConnectAs
void setPosScreen(const QPointF &posScreen)
Set method for position in screen coordinates.
Definition: Point.cpp:510
Container for one set of digitized Points.
Definition: Curve.h:33
void editPointGraph(bool isX, bool isY, double x, double y, const QStringList &identifiers, const Transformation &transformation)
Edit the graph coordinates of one or more graph points. This method does not apply to an axis point...
Definition: Curve.cpp:171
QList< Point > Points
Definition: Points.h:13
void setLineColor(ColorPalette lineColor)
Set method for line color in specified curve.
Definition: CurveStyle.cpp:105
bool transformIsDefined() const
Transform is defined when at least three axis points have been digitized.
log4cpp::Category * mainCat
Definition: Logger.cpp:14
void loadXml(QXmlStreamReader &reader)
Load curve filter to stream.
const QString DEFAULT_GRAPH_CURVE_NAME
void addPoint(const Point &point)
Add Point to this Curve.
Definition: Curve.cpp:134
QString curveConnectAsToString(CurveConnectAs curveConnectAs)
void setPointColor(ColorPalette curveColor)
Set method curve point color in specified curve.
Definition: CurveStyle.cpp:125
Immediately terminate the current search.
CurveStyle curveStyle() const
Return the curve style.
Definition: Curve.cpp:149
const QString SCALE_CURVE_NAME
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition: LineStyle.cpp:63
void printStream(QString indentation, QTextStream &str) const
Debugging method that supports print method of this class and printStream method of some other class(...
void setLineWidth(int width)
Set method for line width in specified curve.
Definition: CurveStyle.cpp:120
void setPointStyle(const PointStyle &pointStyle)
Set method for PointStyle.
Definition: CurveStyle.cpp:145
void transformRawGraphToScreen(const QPointF &pointRaw, QPointF &pointScreen) const
Transform from raw graph coordinates to linear cartesian graph coordinates, then to screen coordinate...
void iterateThroughCurveSegments(const Functor2wRet< const Point &, const Point &, CallbackSearchReturn > &ftorWithCallback) const
Apply functor to successive Points, as line segments, on Curve. This could be a bit slow...
Definition: Curve.cpp:316
void saveXml(QXmlStreamWriter &writer) const
Serialize curve.
Definition: Curve.cpp:523
QMultiMap< double, QString > XOrThetaToPointIdentifier
Definition: Curve.cpp:34
void setOrdinal(double ordinal)
Set the ordinal used for ordering Points.
Definition: Point.cpp:486
const QString DOCUMENT_SERIALIZE_CURVE_NAME
static PointStyle defaultGraphCurve(int index)
Initial default for index&#39;th graph curve.
Definition: PointStyle.cpp:88
CurveConnectAs curveConnectAs(int preVersion6) const
Line drawn between points.
void setCurveName(const QString &curveName)
Update the point identifer to match the specified curve name.
Definition: Point.cpp:471
ColorFilterSettings colorFilterSettings() const
Return the color filter.
Definition: Curve.cpp:139
const QString AXIS_CURVE_NAME
QString curveName() const
Name of this Curve.
Definition: Curve.cpp:144
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT if defined(QT_NO_DEBUG) &amp;&amp; !defined(QT_FORCE_ASSERTS) define ENGAUGE...
Definition: EngaugeAssert.h:20
const QString TAB_DELIMITER("\t")