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 SCALE_CURVE_NAME ("Scale"); // Used for pre-version 6 input files
29 const QString TAB_DELIMITER ("\t");
30 
31 // This has to be a multimap instead of a map since some users may mistakenly allow multiple points with the
32 // same x coordinate in their functions even though that should not happen
33 typedef QMultiMap<double, QString> XOrThetaToPointIdentifier;
34 
35 Curve::Curve(const QString &curveName,
36  const ColorFilterSettings &colorFilterSettings,
37  const CurveStyle &curveStyle) :
38  m_curveName (curveName),
39  m_colorFilterSettings (colorFilterSettings),
40  m_curveStyle (curveStyle)
41 {
42 }
43 
44 Curve::Curve (const Curve &curve) :
45  m_curveName (curve.curveName ()),
46  m_points (curve.points ()),
47  m_colorFilterSettings (curve.colorFilterSettings ()),
48  m_curveStyle (curve.curveStyle ())
49 {
50 }
51 
52 Curve::Curve (QDataStream &str)
53 {
54  const int CONVERT_ENUM_TO_RADIUS = 6;
55  MigrateToVersion6 migrate;
56 
57  qint32 int32, xScreen, yScreen;
58  double xGraph, yGraph;
59 
60  str >> m_curveName;
61 
62  // Scale bar points are handled as if they are axis points
63  if (m_curveName == SCALE_CURVE_NAME) {
64  m_curveName = AXIS_CURVE_NAME;
65  }
66 
67  str >> int32;
68  m_curveStyle.setPointShape(migrate.pointShape (int32));
69  str >> int32;
70  m_curveStyle.setPointRadius(int32 + CONVERT_ENUM_TO_RADIUS);
71  str >> int32;
72  m_curveStyle.setPointLineWidth (int32);
73  str >> int32;
74  m_curveStyle.setPointColor(migrate.colorPalette (int32));
75  str >> int32; // Point interior color
76  str >> int32;
77  m_curveStyle.setLineWidth(int32);
78  str >> int32;
79  if (m_curveName == AXIS_CURVE_NAME) {
80  m_curveStyle.setLineColor(migrate.colorPalette (int32));
81  } else {
82  m_curveStyle.setLineColor(COLOR_PALETTE_TRANSPARENT);
83  }
84  str >> int32;
85  m_curveStyle.setLineConnectAs(migrate.curveConnectAs (int32));
86 
87  str >> int32;
88  int count = int32;
89  int ordinal = 0;
90  for (int i = 0; i < count; i++) {
91 
92  str >> xScreen;
93  str >> yScreen;
94  str >> xGraph;
95  str >> yGraph;
96  if (m_curveName == AXIS_CURVE_NAME) {
97 
98  // Axis point, with graph coordinates set by user and managed here
99  Point point (m_curveName,
100  QPointF (xScreen, yScreen),
101  QPointF (xGraph, yGraph),
102  ordinal++,
103  false);
104 
105  addPoint(point);
106  } else {
107 
108  // Curve point, with graph coordinates managed elsewhere
109  Point point (m_curveName,
110  QPointF (xScreen, yScreen));
111  point.setOrdinal (ordinal++);
112 
113  addPoint(point);
114  }
115  }
116 }
117 
118 Curve::Curve (QXmlStreamReader &reader)
119 {
120  loadXml(reader);
121 }
122 
124 {
125  m_curveName = curve.curveName ();
126  m_points = curve.points ();
127  m_colorFilterSettings = curve.colorFilterSettings ();
128  m_curveStyle = curve.curveStyle ();
129 
130  return *this;
131 }
132 
133 void Curve::addPoint (Point point)
134 {
135  m_points.push_back (point);
136 }
137 
139 {
140  return m_colorFilterSettings;
141 }
142 
143 QString Curve::curveName () const
144 {
145  return m_curveName;
146 }
147 
149 {
150  return m_curveStyle;
151 }
152 
153 void Curve::editPointAxis (const QPointF &posGraph,
154  const QString &identifier)
155 {
156  // Search for the point with matching identifier
157  QList<Point>::iterator itr;
158  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
159 
160  Point &point = *itr;
161  if (point.identifier () == identifier) {
162 
163  point.setPosGraph (posGraph);
164  break;
165 
166  }
167  }
168 }
169 
170 void Curve::editPointGraph (bool isX,
171  bool isY,
172  double x,
173  double y,
174  const QStringList &identifiers,
175  const Transformation &transformation)
176 {
177  LOG4CPP_INFO_S ((*mainCat)) << "Curve::editPointGraph"
178  << " identifiers=" << identifiers.join(" ").toLatin1().data();
179 
180  if (transformation.transformIsDefined()) {
181 
182  // Search for the point with matching identifier
183  QList<Point>::iterator itr;
184  for (itr = m_points.begin(); itr != m_points.end(); itr++) {
185 
186  Point &point = *itr;
187 
188  if (identifiers.contains (point.identifier ())) {
189 
190  // Although one or more graph coordinates are specified, it is the screen coordinates that must be
191  // moved. This is because only the screen coordinates of the graph points are tracked (not the graph coordinates).
192  // So we compute posScreen and call Point::setPosScreen instead of Point::setPosGraph
193 
194  // Get original graph coordinates
195  QPointF posScreen = point.posScreen ();
196  QPointF posGraph;
197  transformation.transformScreenToRawGraph (posScreen,
198  posGraph);
199 
200  // Override one or both coordinates
201  if (isX) {
202  posGraph.setX (x);
203  }
204 
205  if (isY) {
206  posGraph.setY (y);
207  }
208 
209  // Set the screen coordinates
210  transformation.transformRawGraphToScreen(posGraph,
211  posScreen);
212 
213  point.setPosScreen (posScreen);
214  }
215  }
216  }
217 }
218 
219 void Curve::exportToClipboard (const QHash<QString, bool> &selectedHash,
220  const Transformation &transformation,
221  QTextStream &strCsv,
222  QTextStream &strHtml,
223  CurvesGraphs &curvesGraphs) const
224 {
225  LOG4CPP_INFO_S ((*mainCat)) << "Curve::exportToClipboard"
226  << " hashCount=" << selectedHash.count();
227 
228  // This method assumes Copy is only allowed when Transformation is valid
229 
230  bool isFirst = true;
231  QList<Point>::const_iterator itr;
232  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
233 
234  const Point &point = *itr;
235  if (selectedHash.contains (point.identifier ())) {
236 
237  if (isFirst) {
238 
239  // Insert headers to identify the points that follow
240  isFirst = false;
241  strCsv << "X" << TAB_DELIMITER << m_curveName << "\n";
242  strHtml << "<table>\n"
243  << "<tr><th>X</th><th>" << m_curveName << "</th></tr>\n";
244  }
245 
246  // Default curve style
247  CurveStyle curveStyleDefault;
248  curveStyleDefault.setLineStyle(LineStyle::defaultAxesCurve());
249  curveStyleDefault.setPointStyle(PointStyle::defaultGraphCurve (curvesGraphs.numCurves ()));
250 
251  // Check if this curve already exists from a previously exported point
252  if (curvesGraphs.curveForCurveName (m_curveName) == 0) {
253  Curve curve(m_curveName,
255  curveStyleDefault);
256  curvesGraphs.addGraphCurveAtEnd(curve);
257  }
258 
259  // Start with screen coordinates
260  QPointF pos = point.posScreen();
261  if (transformation.transformIsDefined()) {
262 
263  // Replace with graph coordinates which are almost always more useful
264  QPointF posGraph;
265  transformation.transformScreenToRawGraph(pos,
266  posGraph);
267  pos = posGraph;
268  }
269 
270  // Add point to text going to clipboard
271  strCsv << pos.x() << TAB_DELIMITER << pos.y() << "\n";
272  strHtml << "<tr><td>" << pos.x() << "</td><td>" << pos.y() << "</td></tr>\n";
273 
274  // Add point to list for undo/redo
275  curvesGraphs.curveForCurveName (m_curveName)->addPoint (point);
276  }
277  }
278 
279  if (!isFirst) {
280  strHtml << "</table>\n";
281  }
282 }
283 
284 bool Curve::isXOnly(const QString &pointIdentifier) const
285 {
286  // Search for point with matching identifier
287  Points::const_iterator itr;
288  for (itr = m_points.begin (); itr != m_points.end (); itr++) {
289  const Point &point = *itr;
290  if (pointIdentifier == point.identifier ()) {
291  return point.isXOnly();
292  break;
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 
310  if (rtn == CALLBACK_SEARCH_RETURN_INTERRUPT) {
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 = 0;
322  for (itr = m_points.begin(); itr != m_points.end(); itr++) {
323 
324  const Point &point = *itr;
325 
326  if (pointBefore != 0) {
327 
328  CallbackSearchReturn rtn = ftorWithCallback (*pointBefore,
329  point);
330 
331  if (rtn == CALLBACK_SEARCH_RETURN_INTERRUPT) {
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 0;
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 
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 
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 = 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 saveXml(QXmlStreamWriter &writer) const
Serialize to stream.
Definition: Point.cpp:420
void removePoint(const QString &identifier)
Perform the opposite of addPointAtEnd.
Definition: Curve.cpp:510
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:563
ColorFilterSettings colorFilterSettings() const
Return the color filter.
Definition: Curve.cpp:138
void iterateThroughCurvePoints(const Functor2wRet< const QString &, const Point &, CallbackSearchReturn > &ftorWithCallback) const
Apply functor to Points on Curve.
Definition: Curve.cpp:301
void addPoint(Point point)
Add Point to this Curve.
Definition: Curve.cpp:133
void setColorFilterSettings(const ColorFilterSettings &colorFilterSettings)
Set color filter.
Definition: Curve.cpp:546
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:473
void updatePointOrdinals(const Transformation &transformation)
See CurveGraphs::updatePointOrdinals.
Definition: Curve.cpp:568
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:153
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:35
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:451
int numPoints() const
Number of points.
Definition: Curve.cpp:432
Curve & operator=(const Curve &curve)
Assignment constructor.
Definition: Curve.cpp:123
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: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.
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:490
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:316
int numCurves() const
Current number of graphs curves.
void setCurveName(const QString &curveName)
Change the curve name.
Definition: Curve.cpp:551
QString curveName() const
Name of this Curve.
Definition: Curve.cpp:143
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: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:170
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:219
QPointF positionGraph(const QString &pointIdentifier) const
Return the position, in graph coordinates, of the specified Point.
Definition: Curve.cpp:456
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
CurveStyle curveStyle() const
Return the curve style.
Definition: Curve.cpp:148
void saveXml(QXmlStreamWriter &writer) const
Serialize curve.
Definition: Curve.cpp:523
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:284
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