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